File: encode.c

package info (click to toggle)
junkbuster 2.0-3.2
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 676 kB
  • ctags: 978
  • sloc: ansic: 6,639; makefile: 57; sh: 21
file content (157 lines) | stat: -rw-r--r-- 2,818 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
char *encode_rcs = "$Id: encode.c,v 2.7 1997/09/11 03:54:38 ACJC Exp $";
/* Written and copyright 1997 Anonymous Coders and Junkbusters Corporation.
 * Distributed under the GNU General Public License; see the README file.
 * This code comes with NO WARRANTY. http://www.junkbusters.com/ht/en/gpl.html
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#ifdef REGEX
#include "gnu_regex.h"
#endif

#include "jcc.h"

char *url_code_map[256];
char *html_code_map[256];
char *cookie_code_map[256];

char *
url_encode(char **code_map, unsigned char *s)
{
	char *buf;
	unsigned char c, *p;
	char *m;

	static int one_shot = 1;

	if(one_shot) {
		char tmp[BUFSIZ];

		/* initialize the code maps */

		int i;

		one_shot = 0;

		/* for cookies, we turn white-space into '+'
		 * hex encode comma and semi-colons
		 * and leave everything else alone.
		 */

		cookie_code_map[' '] = "+";

		sprintf(tmp, "%%%02X", ',');
		cookie_code_map[','] = strdup(tmp);

		sprintf(tmp, "%%%02X", ';');
		cookie_code_map[';'] = strdup(tmp);

		/* for url's, we do full URL encoding.		*/
		/* non-alphanumerics get turned into hex ...	*/
		for(i=0; i < 256; i++) {
			if(isalnum(i) == 0) {
				sprintf(tmp, "%%%02X", i);
				url_code_map[i] = strdup(tmp);
			}
		}

		/* ... with the following 6 exceptions:		*/
		/* white-space gets turned into '+' ...		*/

		url_code_map[' '] = "+";

		/* ... and these punctuation chars map to themselves */
		url_code_map['-'] = "-";
		url_code_map['_'] = "_";
		url_code_map['.'] = ".";
		url_code_map['*'] = "*";
		url_code_map['@'] = "@";

		/* for html, we encode the four "special" characters */
		html_code_map['"'] = "&quot;" ;
		html_code_map['&'] = "&amp;"  ;
		html_code_map['>'] = "&gt;"   ;
		html_code_map['<'] = "&lt;"   ;
	}

	/* each input char can expand to at most 6 chars */
	buf = zalloc((strlen(s) + 1) * 6);

	for(p = (unsigned char *) buf; (c = *s); s++) {
		if((m = code_map[c])) {
			strcpy((char *) p, m);
			p += strlen(m);
		} else {
			*p++ = c;
		}
	}

	*p = '\0';

	return(buf);
}

/* these decode a URL */

int
xdtoi(char d)
{
	if((d >= '0') && (d <= '9')) return(d - '0'     );
	if((d >= 'a') && (d <= 'f')) return(d - 'a' + 10);
	if((d >= 'A') && (d <= 'F')) return(d - 'A' + 10);
	return(0);
}

int
xtoi(char *s)
{
	char d1, d2;
	int ret = 0;

	if(isxdigit(*s)) {
		d1 = *s++;
		if(isxdigit(*s)) {
			d2 = *s++;
			
			ret = (xdtoi(d1) * 16) + xdtoi(d2);
		}
	}

	return(ret);
}

char *
url_decode(char *str)
{
	char *ret = strdup(str);
	char *p, *q;

	p = str;
	q = ret;

	while(*p) {
		switch(*p) {
		case '+':
			p++;
			*q++ = ' ';
			break;
		case '%':
			if((*q = xtoi(p+1))) {
				p += 3;
				q++;
			} else {
				/* malformed, just use it */
				*q++ = *p++;
			}
			break;
		default:
			*q++ = *p++;
			break;
		}
	}
	*q = '\0';
	return(ret);
}