xref: /plan9/sys/src/libhttpd/httpunesc.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1*9a747e4fSDavid du Colombier #include <u.h>
2*9a747e4fSDavid du Colombier #include <libc.h>
3*9a747e4fSDavid du Colombier #include <bin.h>
4*9a747e4fSDavid du Colombier #include <httpd.h>
5*9a747e4fSDavid du Colombier 
6*9a747e4fSDavid du Colombier /*
7*9a747e4fSDavid du Colombier  *  go from http with latin1 escapes to utf,
8*9a747e4fSDavid du Colombier  *  we assume that anything >= Runeself is already in utf
9*9a747e4fSDavid du Colombier  */
10*9a747e4fSDavid du Colombier char *
httpunesc(HConnect * cc,char * s)11*9a747e4fSDavid du Colombier httpunesc(HConnect *cc, char *s)
12*9a747e4fSDavid du Colombier {
13*9a747e4fSDavid du Colombier 	char *t, *v;
14*9a747e4fSDavid du Colombier 	int c;
15*9a747e4fSDavid du Colombier 	Htmlesc *e;
16*9a747e4fSDavid du Colombier 
17*9a747e4fSDavid du Colombier 	v = halloc(cc, UTFmax*strlen(s) + 1);
18*9a747e4fSDavid du Colombier 	for(t = v; c = *s;){
19*9a747e4fSDavid du Colombier 		if(c == '&'){
20*9a747e4fSDavid du Colombier 			if(s[1] == '#' && s[2] && s[3] && s[4] && s[5] == ';'){
21*9a747e4fSDavid du Colombier 				c = atoi(s+2);
22*9a747e4fSDavid du Colombier 				if(c < Runeself){
23*9a747e4fSDavid du Colombier 					*t++ = c;
24*9a747e4fSDavid du Colombier 					s += 6;
25*9a747e4fSDavid du Colombier 					continue;
26*9a747e4fSDavid du Colombier 				}
27*9a747e4fSDavid du Colombier 				if(c < 256 && c >= 161){
28*9a747e4fSDavid du Colombier 					e = &htmlesc[c-161];
29*9a747e4fSDavid du Colombier 					t += runetochar(t, &e->value);
30*9a747e4fSDavid du Colombier 					s += 6;
31*9a747e4fSDavid du Colombier 					continue;
32*9a747e4fSDavid du Colombier 				}
33*9a747e4fSDavid du Colombier 			} else {
34*9a747e4fSDavid du Colombier 				for(e = htmlesc; e->name != nil; e++)
35*9a747e4fSDavid du Colombier 					if(strncmp(e->name, s, strlen(e->name)) == 0)
36*9a747e4fSDavid du Colombier 						break;
37*9a747e4fSDavid du Colombier 				if(e->name != nil){
38*9a747e4fSDavid du Colombier 					t += runetochar(t, &e->value);
39*9a747e4fSDavid du Colombier 					s += strlen(e->name);
40*9a747e4fSDavid du Colombier 					continue;
41*9a747e4fSDavid du Colombier 				}
42*9a747e4fSDavid du Colombier 			}
43*9a747e4fSDavid du Colombier 		}
44*9a747e4fSDavid du Colombier 		*t++ = c;
45*9a747e4fSDavid du Colombier 		s++;
46*9a747e4fSDavid du Colombier 	}
47*9a747e4fSDavid du Colombier 	*t = 0;
48*9a747e4fSDavid du Colombier 	return v;
49*9a747e4fSDavid du Colombier }
50