1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2007 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Author: Hartmut Holzgraefe <hholzgra@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 : /* $Id: url_scanner.c,v 1.44.2.1.2.3 2007/02/22 00:44:08 iliaa Exp $ */
19 :
20 : #include "php.h"
21 :
22 : #include "php_globals.h"
23 :
24 : #include <sys/types.h>
25 : #include <stdio.h>
26 : #include <stdlib.h>
27 : #include <string.h>
28 : #include "basic_functions.h"
29 : #include "url_scanner.h"
30 :
31 : #ifndef BUFSIZE
32 : #define BUFSIZE 256
33 : #endif
34 :
35 : int php_url_scanner_activate(TSRMLS_D)
36 0 : {
37 0 : url_adapt(NULL,0,NULL,NULL);
38 0 : return SUCCESS;
39 : }
40 :
41 :
42 : int php_url_scanner_deactivate(TSRMLS_D)
43 0 : {
44 0 : url_adapt(NULL,0,NULL,NULL);
45 0 : return SUCCESS;
46 : }
47 :
48 : /* {{{ url_attr_addon
49 : */
50 : static char *url_attr_addon(const char *tag,const char *attr,const char *val,const char *buf)
51 0 : {
52 0 : int flag = 0;
53 :
54 0 : if (!strcasecmp(tag,"a") && !strcasecmp(attr,"href")) {
55 0 : flag = 1;
56 0 : } else if (!strcasecmp(tag,"area" ) && !strcasecmp(attr,"href" )) {
57 0 : flag = 1;
58 0 : } else if (!strcasecmp(tag,"form" ) && !strcasecmp(attr,"action" )) {
59 0 : flag = 1;
60 0 : } else if (!strcasecmp(tag,"frame") && !strcasecmp(attr,"source" )) {
61 0 : flag = 1;
62 0 : } else if (!strcasecmp(tag,"img" ) && !strcasecmp(attr,"action" )) {
63 0 : flag = 1;
64 : }
65 0 : if(flag && !strstr(val,buf) && !strchr(val,':')) {
66 : char *result;
67 : TSRMLS_FETCH();
68 :
69 0 : spprintf(&result, 0, "%s%s", (strchr(val,'?') ? PG(arg_separator).output : "?"), buf);
70 0 : return result;
71 : }
72 0 : return NULL;
73 : }
74 : /* }}} */
75 :
76 : #define US BG(url_adapt_state)
77 :
78 : /* {{{ url_adapt_ext
79 : */
80 : char *url_adapt_ext(const char *src, uint srclen, const char *name, const char *val, size_t *newlen)
81 0 : {
82 : char buf[1024];
83 :
84 0 : snprintf(buf, sizeof(buf)-1, "%s=%s", name, val);
85 :
86 0 : return url_adapt(src, srclen, buf, newlen);
87 : }
88 : /* }}} */
89 :
90 : /* {{{ url_adapt
91 : */
92 : char *url_adapt(const char *src, size_t srclen, const char *data, size_t *newlen)
93 0 : {
94 : char *out,*outp;
95 : int maxl,n;
96 : TSRMLS_FETCH();
97 :
98 0 : if(src==NULL) {
99 0 : US.state=STATE_NORMAL;
100 0 : if(US.tag) { efree(US.tag); US.tag =NULL; }
101 0 : if(US.attr) { efree(US.attr); US.attr=NULL; }
102 0 : if(US.val) { efree(US.val); US.val =NULL; }
103 0 : return NULL;
104 : }
105 :
106 0 : if(srclen==0)
107 0 : srclen=strlen(src);
108 :
109 0 : out=malloc(srclen+1);
110 0 : maxl=srclen;
111 0 : n=srclen;
112 :
113 0 : *newlen=0;
114 0 : outp=out;
115 :
116 0 : while(n--) {
117 0 : switch(US.state) {
118 : case STATE_NORMAL:
119 0 : if(*src=='<')
120 0 : US.state=STATE_TAG_START;
121 0 : break;
122 :
123 : case STATE_TAG_START:
124 0 : if(! isalnum(*src))
125 0 : US.state=STATE_NORMAL;
126 0 : US.state=STATE_TAG;
127 0 : US.ml=BUFSIZE;
128 0 : US.p=US.tag=erealloc(US.tag,US.ml);
129 0 : *(US.p)++=*src;
130 0 : US.l=1;
131 0 : break;
132 :
133 : case STATE_TAG:
134 0 : if(isalnum(*src)) {
135 0 : *(US.p)++ = *src;
136 0 : US.l++;
137 0 : if(US.l==US.ml) {
138 0 : US.ml+=BUFSIZE;
139 0 : US.tag=erealloc(US.tag,US.ml);
140 0 : US.p = US.tag+US.l;
141 : }
142 0 : } else if (isspace(*src)) {
143 0 : US.state = STATE_IN_TAG;
144 0 : *US.p='\0';
145 0 : US.tag=erealloc(US.tag,US.l);
146 : } else {
147 0 : US.state = STATE_NORMAL;
148 0 : efree(US.tag);
149 0 : US.tag=NULL;
150 : }
151 0 : break;
152 :
153 : case STATE_IN_TAG:
154 0 : if(isalnum(*src)) {
155 0 : US.state=STATE_TAG_ATTR;
156 0 : US.ml=BUFSIZE;
157 0 : US.p=US.attr=erealloc(US.attr,US.ml);
158 0 : *(US.p)++=*src;
159 0 : US.l=1;
160 0 : } else if (! isspace(*src)) {
161 0 : US.state = STATE_NORMAL;
162 0 : efree(US.tag);
163 0 : US.tag=NULL;
164 : }
165 0 : break;
166 :
167 : case STATE_TAG_ATTR:
168 0 : if(isalnum(*src)) {
169 0 : *US.p++=*src;
170 0 : ++US.l;
171 0 : if(US.l==US.ml) {
172 0 : US.ml+=BUFSIZE;
173 0 : US.attr=erealloc(US.attr,US.ml);
174 0 : US.p = US.attr+US.l;
175 : }
176 0 : if(US.l==US.ml) {
177 0 : US.ml+=BUFSIZE;
178 0 : US.attr=erealloc(US.attr,US.ml);
179 0 : US.p = US.attr+US.l;
180 : }
181 0 : } else if(isspace(*src)||(*src=='=')){
182 0 : US.state=STATE_TAG_IS;
183 0 : *US.p=0;
184 0 : US.attr=erealloc(US.attr,US.l);
185 0 : } else if(*src=='>') {
186 0 : US.state=STATE_NORMAL;
187 : } else {
188 0 : efree(US.attr);
189 0 : US.attr=NULL;
190 0 : US.state=STATE_IN_TAG;
191 : }
192 0 : break;
193 :
194 : case STATE_TAG_IS:
195 : case STATE_TAG_IS2:
196 0 : if(*src=='>'){
197 0 : US.state=STATE_NORMAL;
198 0 : if(! (US.attr_done)) {
199 : char *p;
200 0 : p=url_attr_addon(US.tag,US.attr,"",data);
201 0 : if(p) {
202 0 : int l= strlen(p);
203 0 : maxl+=l;
204 0 : out=realloc(out,maxl);
205 0 : outp=out+*newlen;
206 0 : strlcpy(outp,p,maxl);
207 0 : outp+=l;
208 0 : *newlen+=l;
209 0 : efree(p);
210 : }
211 : }
212 0 : } else if(*src=='#') {
213 0 : if(! (US.attr_done)) {
214 : char *p;
215 0 : US.attr_done=1;
216 0 : p=url_attr_addon(US.tag,US.attr,"#",data);
217 0 : if(p) {
218 0 : int l= strlen(p);
219 0 : maxl+=l;
220 0 : out=realloc(out,maxl);
221 0 : outp=out+*newlen;
222 0 : strlcpy(outp, p, maxl);
223 0 : outp+=l;
224 0 : *newlen+=l;
225 0 : efree(p);
226 : }
227 : }
228 0 : } else if(!isspace(*src)&&(*src!='=')) {
229 0 : US.ml=BUFSIZE;
230 0 : US.p=US.val=erealloc(US.val,US.ml);
231 0 : US.l=0;
232 0 : US.attr_done=0;
233 0 : if((*src=='"')||(*src=='\'')) {
234 0 : US.state=STATE_TAG_QVAL2;
235 0 : US.delim=*src;
236 : } else {
237 0 : US.state=STATE_TAG_VAL;
238 0 : *US.p++=*src;
239 0 : US.l++;
240 : }
241 : }
242 0 : break;
243 :
244 :
245 : case STATE_TAG_QVAL2:
246 0 : if(*src=='#') {
247 0 : if(! (US.attr_done)) {
248 : char *p;
249 0 : US.attr_done=1;
250 0 : *US.p='\0';
251 0 : p=url_attr_addon(US.tag,US.attr,US.val,data);
252 0 : if(p) {
253 0 : int l= strlen(p);
254 0 : maxl+=l;
255 0 : out=realloc(out,maxl);
256 0 : outp=out+*newlen;
257 0 : strlcpy(outp,p,maxl);
258 0 : outp+=l;
259 0 : *newlen+=l;
260 0 : efree(p);
261 : }
262 : }
263 0 : } else if(*src==US.delim) {
264 0 : US.state=STATE_IN_TAG;
265 0 : *US.p='\0';
266 0 : if(! (US.attr_done)) {
267 : char *p;
268 0 : p=url_attr_addon(US.tag,US.attr,US.val,data);
269 0 : if(p) {
270 0 : int l= strlen(p);
271 0 : maxl+=l;
272 0 : out=realloc(out,maxl);
273 0 : outp=out+*newlen;
274 0 : strlcpy(outp,p,maxl);
275 0 : outp+=l;
276 0 : *newlen+=l;
277 0 : efree(p);
278 : }
279 : }
280 0 : break;
281 0 : } else if(*src=='\\') {
282 0 : US.state=STATE_TAG_QVAL2b;
283 0 : } else if (*src=='>') {
284 0 : US.state=STATE_NORMAL;
285 : }
286 :
287 0 : *US.p++=*src;
288 0 : ++US.l;
289 0 : if(US.l==US.ml) {
290 0 : US.ml+=BUFSIZE;
291 0 : US.val=erealloc(US.val,US.ml);
292 0 : US.p = US.val+US.l;
293 : }
294 :
295 0 : break;
296 :
297 : case STATE_TAG_QVAL2b:
298 0 : US.state=STATE_TAG_QVAL2;
299 0 : *US.p++=*src;
300 0 : ++US.l;
301 0 : if(US.l==US.ml) {
302 0 : US.ml+=BUFSIZE;
303 0 : US.val=erealloc(US.val,US.ml);
304 0 : US.p = US.val+US.l;
305 : }
306 0 : break;
307 :
308 : case STATE_TAG_VAL:
309 : case STATE_TAG_VAL2:
310 0 : if(*src=='#') {
311 0 : if(! (US.attr_done)) {
312 : char *p;
313 0 : US.attr_done=1;
314 0 : *US.p='\0';
315 0 : p=url_attr_addon(US.tag,US.attr,US.val,data);
316 0 : if(p) {
317 0 : int l= strlen(p);
318 0 : maxl+=l;
319 0 : out=realloc(out,maxl);
320 0 : outp=out+*newlen;
321 0 : strlcpy(outp,p,maxl);
322 0 : outp+=l;
323 0 : *newlen+=l;
324 0 : efree(p);
325 : }
326 : }
327 0 : } else if(isspace(*src)||(*src=='>')) {
328 0 : US.state=(*src=='>')?STATE_NORMAL:STATE_IN_TAG;
329 0 : *US.p='\0';
330 0 : if(! (US.attr_done)) {
331 : char *p;
332 0 : p=url_attr_addon(US.tag,US.attr,US.val,data);
333 0 : if(p) {
334 0 : int l= strlen(p);
335 0 : maxl+=l;
336 0 : out=realloc(out,maxl);
337 0 : outp=out+*newlen;
338 0 : strlcpy(outp,p,maxl);
339 0 : outp+=l;
340 0 : *newlen+=l;
341 0 : efree(p);
342 : }
343 : }
344 : } else {
345 0 : *US.p++=*src;
346 0 : US.l++;
347 0 : if(US.l==US.ml) {
348 0 : US.ml+=BUFSIZE;
349 0 : US.val=erealloc(US.val,US.ml);
350 0 : US.p = US.val+US.l;
351 : }
352 : }
353 : break;
354 : default:
355 : break;
356 : }
357 :
358 0 : *outp++=*src++;
359 0 : *newlen+=1;
360 : }
361 0 : *outp='\0';
362 0 : return out;
363 : }
364 : /* }}} */
365 :
366 : /*
367 : * Local variables:
368 : * tab-width: 4
369 : * c-basic-offset: 4
370 : * End:
371 : * vim600: sw=4 ts=4 fdm=marker
372 : * vim<600: sw=4 ts=4
373 : */
|