1 : /* Generated by re2c 0.9.11 on Tue Feb 28 09:38:22 2006 */
2 : #line 1 "ext/standard/url_scanner_ex.re"
3 : /*
4 : +----------------------------------------------------------------------+
5 : | PHP Version 5 |
6 : +----------------------------------------------------------------------+
7 : | Copyright (c) 1997-2007 The PHP Group |
8 : +----------------------------------------------------------------------+
9 : | This source file is subject to version 3.01 of the PHP license, |
10 : | that is bundled with this package in the file LICENSE, and is |
11 : | available through the world-wide-web at the following url: |
12 : | http://www.php.net/license/3_01.txt |
13 : | If you did not receive a copy of the PHP license and are unable to |
14 : | obtain it through the world-wide-web, please send a note to |
15 : | license@php.net so we can mail you a copy immediately. |
16 : +----------------------------------------------------------------------+
17 : | Author: Sascha Schumann <sascha@schumann.cx> |
18 : +----------------------------------------------------------------------+
19 : */
20 :
21 : /* $Id: url_scanner_ex.c,v 1.95.2.4.2.1 2007/01/01 09:36:09 sebastian Exp $ */
22 :
23 : #include "php.h"
24 :
25 : #ifdef HAVE_UNISTD_H
26 : #include <unistd.h>
27 : #endif
28 : #ifdef HAVE_LIMITS_H
29 : #include <limits.h>
30 : #endif
31 :
32 : #include <stdio.h>
33 : #include <stdlib.h>
34 : #include <string.h>
35 :
36 : #include "php_ini.h"
37 : #include "php_globals.h"
38 : #define STATE_TAG SOME_OTHER_STATE_TAG
39 : #include "basic_functions.h"
40 : #include "url.h"
41 : #undef STATE_TAG
42 :
43 : #define url_scanner url_scanner_ex
44 :
45 : #include "php_smart_str.h"
46 :
47 : static PHP_INI_MH(OnUpdateTags)
48 : {
49 : url_adapt_state_ex_t *ctx;
50 : char *key;
51 : char *lasts;
52 : char *tmp;
53 :
54 : ctx = &BG(url_adapt_state_ex);
55 :
56 : tmp = estrndup(new_value, new_value_length);
57 :
58 : if (ctx->tags)
59 : zend_hash_destroy(ctx->tags);
60 : else
61 : ctx->tags = malloc(sizeof(HashTable));
62 :
63 : zend_hash_init(ctx->tags, 0, NULL, NULL, 1);
64 :
65 : for (key = php_strtok_r(tmp, ",", &lasts);
66 : key;
67 : key = php_strtok_r(NULL, ",", &lasts)) {
68 : char *val;
69 :
70 : val = strchr(key, '=');
71 : if (val) {
72 : char *q;
73 : int keylen;
74 :
75 : *val++ = '\0';
76 : for (q = key; *q; q++)
77 : *q = tolower(*q);
78 : keylen = q - key;
79 : /* key is stored withOUT NUL
80 : val is stored WITH NUL */
81 : zend_hash_add(ctx->tags, key, keylen, val, strlen(val)+1, NULL);
82 : }
83 : }
84 :
85 : efree(tmp);
86 :
87 : return SUCCESS;
88 : }
89 :
90 : PHP_INI_BEGIN()
91 : STD_PHP_INI_ENTRY("url_rewriter.tags", "a=href,area=href,frame=src,form=,fieldset=", PHP_INI_ALL, OnUpdateTags, url_adapt_state_ex, php_basic_globals, basic_globals)
92 : PHP_INI_END()
93 :
94 : #line 97 "ext/standard/url_scanner_ex.re"
95 :
96 :
97 : #define YYFILL(n) goto done
98 : #define YYCTYPE unsigned char
99 : #define YYCURSOR p
100 : #define YYLIMIT q
101 : #define YYMARKER r
102 :
103 : static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator)
104 : {
105 : register const char *p, *q;
106 : const char *bash = NULL;
107 : const char *sep = "?";
108 :
109 : q = (p = url->c) + url->len;
110 :
111 : scan:
112 :
113 : #line 114 "ext/standard/url_scanner_ex.c"
114 : {
115 : YYCTYPE yych;
116 0 : goto yy0;
117 : ++YYCURSOR;
118 0 : yy0:
119 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
120 0 : yych = *YYCURSOR;
121 0 : switch(yych){
122 0 : case '#': goto yy6;
123 0 : case ':': goto yy2;
124 0 : case '?': goto yy4;
125 0 : default: goto yy8;
126 : }
127 0 : yy2: ++YYCURSOR;
128 : goto yy3;
129 0 : yy3:
130 : #line 115 "ext/standard/url_scanner_ex.re"
131 : { smart_str_append(dest, url); return; }
132 : #line 133 "ext/standard/url_scanner_ex.c"
133 0 : yy4: ++YYCURSOR;
134 : goto yy5;
135 0 : yy5:
136 : #line 116 "ext/standard/url_scanner_ex.re"
137 : { sep = separator; goto scan; }
138 : #line 139 "ext/standard/url_scanner_ex.c"
139 0 : yy6: ++YYCURSOR;
140 : goto yy7;
141 0 : yy7:
142 : #line 117 "ext/standard/url_scanner_ex.re"
143 : { bash = p - 1; goto done; }
144 : #line 145 "ext/standard/url_scanner_ex.c"
145 0 : yy8: ++YYCURSOR;
146 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
147 0 : yych = *YYCURSOR;
148 : goto yy9;
149 0 : yy9: switch(yych){
150 0 : case '#': case ':': case '?': goto yy10;
151 0 : default: goto yy8;
152 : }
153 0 : yy10:
154 : #line 118 "ext/standard/url_scanner_ex.re"
155 : { goto scan; }
156 : #line 157 "ext/standard/url_scanner_ex.c"
157 : }
158 : #line 119 "ext/standard/url_scanner_ex.re"
159 :
160 : done:
161 :
162 : /* Don't modify URLs of the format "#mark" */
163 : if (bash && bash - url->c == 0) {
164 : smart_str_append(dest, url);
165 : return;
166 : }
167 :
168 : if (bash)
169 : smart_str_appendl(dest, url->c, bash - url->c);
170 : else
171 : smart_str_append(dest, url);
172 :
173 : smart_str_appends(dest, sep);
174 : smart_str_append(dest, url_app);
175 :
176 : if (bash)
177 : smart_str_appendl(dest, bash, q - bash);
178 : }
179 :
180 :
181 : #undef YYFILL
182 : #undef YYCTYPE
183 : #undef YYCURSOR
184 : #undef YYLIMIT
185 : #undef YYMARKER
186 :
187 : static inline void tag_arg(url_adapt_state_ex_t *ctx, char quotes, char type TSRMLS_DC)
188 : {
189 : char f = 0;
190 :
191 : if (strncasecmp(ctx->arg.c, ctx->lookup_data, ctx->arg.len) == 0)
192 : f = 1;
193 :
194 : if (quotes)
195 : smart_str_appendc(&ctx->result, type);
196 : if (f) {
197 : append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output);
198 : } else {
199 : smart_str_append(&ctx->result, &ctx->val);
200 : }
201 : if (quotes)
202 : smart_str_appendc(&ctx->result, type);
203 : }
204 :
205 : enum {
206 : STATE_PLAIN = 0,
207 : STATE_TAG,
208 : STATE_NEXT_ARG,
209 : STATE_ARG,
210 : STATE_BEFORE_VAL,
211 : STATE_VAL
212 : };
213 :
214 : #define YYFILL(n) goto stop
215 : #define YYCTYPE unsigned char
216 : #define YYCURSOR xp
217 : #define YYLIMIT end
218 : #define YYMARKER q
219 : #define STATE ctx->state
220 :
221 : #define STD_PARA url_adapt_state_ex_t *ctx, char *start, char *YYCURSOR TSRMLS_DC
222 : #define STD_ARGS ctx, start, xp TSRMLS_CC
223 :
224 : #if SCANNER_DEBUG
225 : #define scdebug(x) printf x
226 : #else
227 : #define scdebug(x)
228 : #endif
229 :
230 : static inline void passthru(STD_PARA)
231 : {
232 : scdebug(("appending %d chars, starting with %c\n", YYCURSOR-start, *start));
233 : smart_str_appendl(&ctx->result, start, YYCURSOR - start);
234 : }
235 :
236 : /*
237 : * This function appends a hidden input field after a <form> or
238 : * <fieldset>. The latter is important for XHTML.
239 : */
240 :
241 : static void handle_form(STD_PARA)
242 : {
243 : int doit = 0;
244 :
245 : if (ctx->form_app.len > 0) {
246 : switch (ctx->tag.len) {
247 :
248 : #define RECOGNIZE(x) do { \
249 : case sizeof(x)-1: \
250 : if (strncasecmp(ctx->tag.c, x, sizeof(x)-1) == 0) \
251 : doit = 1; \
252 : break; \
253 : } while (0)
254 :
255 : RECOGNIZE("form");
256 : RECOGNIZE("fieldset");
257 : }
258 :
259 : if (doit)
260 : smart_str_append(&ctx->result, &ctx->form_app);
261 : }
262 : }
263 :
264 :
265 :
266 : /*
267 : * HANDLE_TAG copies the HTML Tag and checks whether we
268 : * have that tag in our table. If we might modify it,
269 : * we continue to scan the tag, otherwise we simply copy the complete
270 : * HTML stuff to the result buffer.
271 : */
272 :
273 : static inline void handle_tag(STD_PARA)
274 : {
275 : int ok = 0;
276 : int i;
277 :
278 : ctx->tag.len = 0;
279 : smart_str_appendl(&ctx->tag, start, YYCURSOR - start);
280 : for (i = 0; i < ctx->tag.len; i++)
281 : ctx->tag.c[i] = tolower((int)(unsigned char)ctx->tag.c[i]);
282 : if (zend_hash_find(ctx->tags, ctx->tag.c, ctx->tag.len, (void **) &ctx->lookup_data) == SUCCESS)
283 : ok = 1;
284 : STATE = ok ? STATE_NEXT_ARG : STATE_PLAIN;
285 : }
286 :
287 : static inline void handle_arg(STD_PARA)
288 : {
289 : ctx->arg.len = 0;
290 : smart_str_appendl(&ctx->arg, start, YYCURSOR - start);
291 : }
292 :
293 : static inline void handle_val(STD_PARA, char quotes, char type)
294 : {
295 : smart_str_setl(&ctx->val, start + quotes, YYCURSOR - start - quotes * 2);
296 : tag_arg(ctx, quotes, type TSRMLS_CC);
297 : }
298 :
299 : static inline void xx_mainloop(url_adapt_state_ex_t *ctx, const char *newdata, size_t newlen TSRMLS_DC)
300 : {
301 : char *end, *q;
302 : char *xp;
303 : char *start;
304 : int rest;
305 :
306 : smart_str_appendl(&ctx->buf, newdata, newlen);
307 :
308 : YYCURSOR = ctx->buf.c;
309 : YYLIMIT = ctx->buf.c + ctx->buf.len;
310 :
311 : switch (STATE) {
312 : case STATE_PLAIN: goto state_plain;
313 : case STATE_TAG: goto state_tag;
314 : case STATE_NEXT_ARG: goto state_next_arg;
315 : case STATE_ARG: goto state_arg;
316 : case STATE_BEFORE_VAL: goto state_before_val;
317 : case STATE_VAL: goto state_val;
318 : }
319 :
320 :
321 : state_plain_begin:
322 : STATE = STATE_PLAIN;
323 :
324 : state_plain:
325 : start = YYCURSOR;
326 :
327 : #line 328 "ext/standard/url_scanner_ex.c"
328 : {
329 : YYCTYPE yych;
330 0 : goto yy11;
331 : ++YYCURSOR;
332 0 : yy11:
333 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
334 0 : yych = *YYCURSOR;
335 0 : switch(yych){
336 0 : case '<': goto yy13;
337 0 : default: goto yy15;
338 : }
339 0 : yy13: ++YYCURSOR;
340 : goto yy14;
341 0 : yy14:
342 : #line 287 "ext/standard/url_scanner_ex.re"
343 : { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
344 : #line 345 "ext/standard/url_scanner_ex.c"
345 0 : yy15: ++YYCURSOR;
346 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
347 0 : yych = *YYCURSOR;
348 : goto yy16;
349 0 : yy16: switch(yych){
350 0 : case '<': goto yy17;
351 0 : default: goto yy15;
352 : }
353 0 : yy17:
354 : #line 288 "ext/standard/url_scanner_ex.re"
355 : { passthru(STD_ARGS); goto state_plain; }
356 : #line 357 "ext/standard/url_scanner_ex.c"
357 : }
358 : #line 289 "ext/standard/url_scanner_ex.re"
359 :
360 :
361 : state_tag:
362 : start = YYCURSOR;
363 :
364 : #line 365 "ext/standard/url_scanner_ex.c"
365 : {
366 : YYCTYPE yych;
367 0 : goto yy18;
368 : ++YYCURSOR;
369 0 : yy18:
370 0 : if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
371 0 : yych = *YYCURSOR;
372 0 : switch(yych){
373 : case 'A':
374 : case 'B':
375 : case 'C':
376 : case 'D':
377 : case 'E':
378 : case 'F':
379 : case 'G':
380 : case 'H':
381 : case 'I':
382 : case 'J':
383 : case 'K':
384 : case 'L':
385 : case 'M':
386 : case 'N':
387 : case 'O':
388 : case 'P':
389 : case 'Q':
390 : case 'R':
391 : case 'S':
392 : case 'T':
393 : case 'U':
394 : case 'V':
395 : case 'W':
396 : case 'X':
397 : case 'Y':
398 : case 'Z': case 'a':
399 : case 'b':
400 : case 'c':
401 : case 'd':
402 : case 'e':
403 : case 'f':
404 : case 'g':
405 : case 'h':
406 : case 'i':
407 : case 'j':
408 : case 'k':
409 : case 'l':
410 : case 'm':
411 : case 'n':
412 : case 'o':
413 : case 'p':
414 : case 'q':
415 : case 'r':
416 : case 's':
417 : case 't':
418 : case 'u':
419 : case 'v':
420 : case 'w':
421 : case 'x':
422 : case 'y':
423 0 : case 'z': goto yy20;
424 0 : default: goto yy22;
425 : }
426 0 : yy20: ++YYCURSOR;
427 0 : yych = *YYCURSOR;
428 0 : goto yy25;
429 0 : yy21:
430 : #line 294 "ext/standard/url_scanner_ex.re"
431 : { handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; }
432 : #line 433 "ext/standard/url_scanner_ex.c"
433 0 : yy22: ++YYCURSOR;
434 : goto yy23;
435 0 : yy23:
436 : #line 295 "ext/standard/url_scanner_ex.re"
437 : { passthru(STD_ARGS); goto state_plain_begin; }
438 : #line 439 "ext/standard/url_scanner_ex.c"
439 0 : yy24: ++YYCURSOR;
440 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
441 0 : yych = *YYCURSOR;
442 : goto yy25;
443 0 : yy25: switch(yych){
444 : case 'A':
445 : case 'B':
446 : case 'C':
447 : case 'D':
448 : case 'E':
449 : case 'F':
450 : case 'G':
451 : case 'H':
452 : case 'I':
453 : case 'J':
454 : case 'K':
455 : case 'L':
456 : case 'M':
457 : case 'N':
458 : case 'O':
459 : case 'P':
460 : case 'Q':
461 : case 'R':
462 : case 'S':
463 : case 'T':
464 : case 'U':
465 : case 'V':
466 : case 'W':
467 : case 'X':
468 : case 'Y':
469 : case 'Z': case 'a':
470 : case 'b':
471 : case 'c':
472 : case 'd':
473 : case 'e':
474 : case 'f':
475 : case 'g':
476 : case 'h':
477 : case 'i':
478 : case 'j':
479 : case 'k':
480 : case 'l':
481 : case 'm':
482 : case 'n':
483 : case 'o':
484 : case 'p':
485 : case 'q':
486 : case 'r':
487 : case 's':
488 : case 't':
489 : case 'u':
490 : case 'v':
491 : case 'w':
492 : case 'x':
493 : case 'y':
494 0 : case 'z': goto yy24;
495 0 : default: goto yy21;
496 : }
497 : }
498 : #line 296 "ext/standard/url_scanner_ex.re"
499 :
500 :
501 : state_next_arg_begin:
502 : STATE = STATE_NEXT_ARG;
503 :
504 : state_next_arg:
505 : start = YYCURSOR;
506 :
507 : #line 508 "ext/standard/url_scanner_ex.c"
508 : {
509 : YYCTYPE yych;
510 0 : goto yy26;
511 : ++YYCURSOR;
512 0 : yy26:
513 0 : if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
514 0 : yych = *YYCURSOR;
515 0 : switch(yych){
516 : case 0x09:
517 : case 0x0A:
518 0 : case 0x0B: case 0x0D: case ' ': goto yy30;
519 0 : case '>': goto yy28;
520 : case 'A':
521 : case 'B':
522 : case 'C':
523 : case 'D':
524 : case 'E':
525 : case 'F':
526 : case 'G':
527 : case 'H':
528 : case 'I':
529 : case 'J':
530 : case 'K':
531 : case 'L':
532 : case 'M':
533 : case 'N':
534 : case 'O':
535 : case 'P':
536 : case 'Q':
537 : case 'R':
538 : case 'S':
539 : case 'T':
540 : case 'U':
541 : case 'V':
542 : case 'W':
543 : case 'X':
544 : case 'Y':
545 : case 'Z': case 'a':
546 : case 'b':
547 : case 'c':
548 : case 'd':
549 : case 'e':
550 : case 'f':
551 : case 'g':
552 : case 'h':
553 : case 'i':
554 : case 'j':
555 : case 'k':
556 : case 'l':
557 : case 'm':
558 : case 'n':
559 : case 'o':
560 : case 'p':
561 : case 'q':
562 : case 'r':
563 : case 's':
564 : case 't':
565 : case 'u':
566 : case 'v':
567 : case 'w':
568 : case 'x':
569 : case 'y':
570 0 : case 'z': goto yy32;
571 0 : default: goto yy34;
572 : }
573 0 : yy28: ++YYCURSOR;
574 : goto yy29;
575 0 : yy29:
576 : #line 304 "ext/standard/url_scanner_ex.re"
577 : { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
578 : #line 579 "ext/standard/url_scanner_ex.c"
579 0 : yy30: ++YYCURSOR;
580 0 : yych = *YYCURSOR;
581 0 : goto yy37;
582 0 : yy31:
583 : #line 305 "ext/standard/url_scanner_ex.re"
584 : { passthru(STD_ARGS); goto state_next_arg; }
585 : #line 586 "ext/standard/url_scanner_ex.c"
586 0 : yy32: ++YYCURSOR;
587 : goto yy33;
588 0 : yy33:
589 : #line 306 "ext/standard/url_scanner_ex.re"
590 : { --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
591 : #line 592 "ext/standard/url_scanner_ex.c"
592 0 : yy34: ++YYCURSOR;
593 : goto yy35;
594 0 : yy35:
595 : #line 307 "ext/standard/url_scanner_ex.re"
596 : { passthru(STD_ARGS); goto state_plain_begin; }
597 : #line 598 "ext/standard/url_scanner_ex.c"
598 0 : yy36: ++YYCURSOR;
599 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
600 0 : yych = *YYCURSOR;
601 : goto yy37;
602 0 : yy37: switch(yych){
603 : case 0x09:
604 : case 0x0A:
605 0 : case 0x0B: case 0x0D: case ' ': goto yy36;
606 0 : default: goto yy31;
607 : }
608 : }
609 : #line 308 "ext/standard/url_scanner_ex.re"
610 :
611 :
612 : state_arg:
613 : start = YYCURSOR;
614 :
615 : #line 616 "ext/standard/url_scanner_ex.c"
616 : {
617 : YYCTYPE yych;
618 0 : goto yy38;
619 : ++YYCURSOR;
620 0 : yy38:
621 0 : if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
622 0 : yych = *YYCURSOR;
623 0 : switch(yych){
624 : case 'A':
625 : case 'B':
626 : case 'C':
627 : case 'D':
628 : case 'E':
629 : case 'F':
630 : case 'G':
631 : case 'H':
632 : case 'I':
633 : case 'J':
634 : case 'K':
635 : case 'L':
636 : case 'M':
637 : case 'N':
638 : case 'O':
639 : case 'P':
640 : case 'Q':
641 : case 'R':
642 : case 'S':
643 : case 'T':
644 : case 'U':
645 : case 'V':
646 : case 'W':
647 : case 'X':
648 : case 'Y':
649 : case 'Z': case 'a':
650 : case 'b':
651 : case 'c':
652 : case 'd':
653 : case 'e':
654 : case 'f':
655 : case 'g':
656 : case 'h':
657 : case 'i':
658 : case 'j':
659 : case 'k':
660 : case 'l':
661 : case 'm':
662 : case 'n':
663 : case 'o':
664 : case 'p':
665 : case 'q':
666 : case 'r':
667 : case 's':
668 : case 't':
669 : case 'u':
670 : case 'v':
671 : case 'w':
672 : case 'x':
673 : case 'y':
674 0 : case 'z': goto yy40;
675 0 : default: goto yy42;
676 : }
677 0 : yy40: ++YYCURSOR;
678 0 : yych = *YYCURSOR;
679 0 : goto yy45;
680 0 : yy41:
681 : #line 313 "ext/standard/url_scanner_ex.re"
682 : { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
683 : #line 684 "ext/standard/url_scanner_ex.c"
684 0 : yy42: ++YYCURSOR;
685 : goto yy43;
686 0 : yy43:
687 : #line 314 "ext/standard/url_scanner_ex.re"
688 : { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
689 : #line 690 "ext/standard/url_scanner_ex.c"
690 0 : yy44: ++YYCURSOR;
691 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
692 0 : yych = *YYCURSOR;
693 : goto yy45;
694 0 : yy45: switch(yych){
695 : case '-': case 'A':
696 : case 'B':
697 : case 'C':
698 : case 'D':
699 : case 'E':
700 : case 'F':
701 : case 'G':
702 : case 'H':
703 : case 'I':
704 : case 'J':
705 : case 'K':
706 : case 'L':
707 : case 'M':
708 : case 'N':
709 : case 'O':
710 : case 'P':
711 : case 'Q':
712 : case 'R':
713 : case 'S':
714 : case 'T':
715 : case 'U':
716 : case 'V':
717 : case 'W':
718 : case 'X':
719 : case 'Y':
720 : case 'Z': case 'a':
721 : case 'b':
722 : case 'c':
723 : case 'd':
724 : case 'e':
725 : case 'f':
726 : case 'g':
727 : case 'h':
728 : case 'i':
729 : case 'j':
730 : case 'k':
731 : case 'l':
732 : case 'm':
733 : case 'n':
734 : case 'o':
735 : case 'p':
736 : case 'q':
737 : case 'r':
738 : case 's':
739 : case 't':
740 : case 'u':
741 : case 'v':
742 : case 'w':
743 : case 'x':
744 : case 'y':
745 0 : case 'z': goto yy44;
746 0 : default: goto yy41;
747 : }
748 : }
749 : #line 315 "ext/standard/url_scanner_ex.re"
750 :
751 :
752 : state_before_val:
753 : start = YYCURSOR;
754 :
755 : #line 756 "ext/standard/url_scanner_ex.c"
756 : {
757 : YYCTYPE yych;
758 0 : unsigned int yyaccept = 0;
759 0 : goto yy46;
760 : ++YYCURSOR;
761 0 : yy46:
762 0 : if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
763 0 : yych = *YYCURSOR;
764 0 : switch(yych){
765 0 : case ' ': goto yy48;
766 0 : case '=': goto yy50;
767 0 : default: goto yy52;
768 : }
769 0 : yy48: yyaccept = 0;
770 0 : yych = *(YYMARKER = ++YYCURSOR);
771 0 : switch(yych){
772 0 : case ' ': goto yy55;
773 0 : case '=': goto yy53;
774 : default: goto yy49;
775 : }
776 0 : yy49:
777 : #line 321 "ext/standard/url_scanner_ex.re"
778 : { --YYCURSOR; goto state_next_arg_begin; }
779 : #line 780 "ext/standard/url_scanner_ex.c"
780 0 : yy50: ++YYCURSOR;
781 0 : yych = *YYCURSOR;
782 0 : goto yy54;
783 0 : yy51:
784 : #line 320 "ext/standard/url_scanner_ex.re"
785 : { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
786 : #line 787 "ext/standard/url_scanner_ex.c"
787 0 : yy52: yych = *++YYCURSOR;
788 0 : goto yy49;
789 0 : yy53: ++YYCURSOR;
790 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
791 0 : yych = *YYCURSOR;
792 : goto yy54;
793 0 : yy54: switch(yych){
794 0 : case ' ': goto yy53;
795 0 : default: goto yy51;
796 : }
797 0 : yy55: ++YYCURSOR;
798 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
799 0 : yych = *YYCURSOR;
800 : goto yy56;
801 0 : yy56: switch(yych){
802 0 : case ' ': goto yy55;
803 0 : case '=': goto yy53;
804 : default: goto yy57;
805 : }
806 0 : yy57: YYCURSOR = YYMARKER;
807 0 : switch(yyaccept){
808 0 : case 0: goto yy49;
809 : }
810 : }
811 : #line 322 "ext/standard/url_scanner_ex.re"
812 :
813 :
814 :
815 : state_val:
816 : start = YYCURSOR;
817 :
818 : #line 819 "ext/standard/url_scanner_ex.c"
819 : {
820 : YYCTYPE yych;
821 0 : unsigned int yyaccept = 0;
822 0 : goto yy58;
823 : ++YYCURSOR;
824 0 : yy58:
825 0 : if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
826 0 : yych = *YYCURSOR;
827 0 : switch(yych){
828 : case 0x09:
829 0 : case 0x0A: case 0x0D: case ' ': case '>': goto yy64;
830 0 : case '"': goto yy60;
831 0 : case '\'': goto yy62;
832 0 : default: goto yy63;
833 : }
834 0 : yy60: yyaccept = 0;
835 0 : yych = *(YYMARKER = ++YYCURSOR);
836 0 : goto yy77;
837 0 : yy61:
838 : #line 330 "ext/standard/url_scanner_ex.re"
839 : { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
840 : #line 841 "ext/standard/url_scanner_ex.c"
841 0 : yy62: yyaccept = 0;
842 0 : yych = *(YYMARKER = ++YYCURSOR);
843 0 : goto yy69;
844 0 : yy63: yych = *++YYCURSOR;
845 0 : goto yy67;
846 0 : yy64: ++YYCURSOR;
847 : goto yy65;
848 0 : yy65:
849 : #line 331 "ext/standard/url_scanner_ex.re"
850 : { passthru(STD_ARGS); goto state_next_arg_begin; }
851 : #line 852 "ext/standard/url_scanner_ex.c"
852 0 : yy66: ++YYCURSOR;
853 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
854 0 : yych = *YYCURSOR;
855 : goto yy67;
856 0 : yy67: switch(yych){
857 : case 0x09:
858 0 : case 0x0A: case 0x0D: case ' ': case '>': goto yy61;
859 0 : default: goto yy66;
860 : }
861 0 : yy68: yyaccept = 0;
862 0 : YYMARKER = ++YYCURSOR;
863 0 : if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
864 0 : yych = *YYCURSOR;
865 : goto yy69;
866 0 : yy69: switch(yych){
867 : case 0x09:
868 0 : case 0x0A: case 0x0D: case ' ': goto yy72;
869 0 : case '\'': goto yy70;
870 0 : case '>': goto yy61;
871 0 : default: goto yy68;
872 : }
873 0 : yy70: ++YYCURSOR;
874 0 : switch((yych = *YYCURSOR)) {
875 : case 0x09:
876 0 : case 0x0A: case 0x0D: case ' ': case '>': goto yy71;
877 0 : default: goto yy66;
878 : }
879 0 : yy71:
880 : #line 329 "ext/standard/url_scanner_ex.re"
881 : { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
882 : #line 883 "ext/standard/url_scanner_ex.c"
883 0 : yy72: ++YYCURSOR;
884 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
885 0 : yych = *YYCURSOR;
886 : goto yy73;
887 0 : yy73: switch(yych){
888 0 : case '\'': goto yy75;
889 0 : case '>': goto yy74;
890 0 : default: goto yy72;
891 : }
892 0 : yy74: YYCURSOR = YYMARKER;
893 0 : switch(yyaccept){
894 0 : case 0: goto yy61;
895 : }
896 0 : yy75: yych = *++YYCURSOR;
897 0 : goto yy71;
898 0 : yy76: yyaccept = 0;
899 0 : YYMARKER = ++YYCURSOR;
900 0 : if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
901 0 : yych = *YYCURSOR;
902 : goto yy77;
903 0 : yy77: switch(yych){
904 : case 0x09:
905 0 : case 0x0A: case 0x0D: case ' ': goto yy80;
906 0 : case '"': goto yy78;
907 0 : case '>': goto yy61;
908 0 : default: goto yy76;
909 : }
910 0 : yy78: ++YYCURSOR;
911 0 : switch((yych = *YYCURSOR)) {
912 : case 0x09:
913 0 : case 0x0A: case 0x0D: case ' ': case '>': goto yy79;
914 0 : default: goto yy66;
915 : }
916 0 : yy79:
917 : #line 328 "ext/standard/url_scanner_ex.re"
918 : { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
919 : #line 920 "ext/standard/url_scanner_ex.c"
920 0 : yy80: ++YYCURSOR;
921 0 : if(YYLIMIT == YYCURSOR) YYFILL(1);
922 0 : yych = *YYCURSOR;
923 : goto yy81;
924 0 : yy81: switch(yych){
925 0 : case '"': goto yy82;
926 0 : case '>': goto yy74;
927 0 : default: goto yy80;
928 : }
929 0 : yy82: ++YYCURSOR;
930 0 : yych = *YYCURSOR;
931 0 : goto yy79;
932 : }
933 : #line 332 "ext/standard/url_scanner_ex.re"
934 :
935 :
936 : stop:
937 : rest = YYLIMIT - start;
938 : scdebug(("stopped in state %d at pos %d (%d:%c) %d\n", STATE, YYCURSOR - ctx->buf.c, *YYCURSOR, *YYCURSOR, rest));
939 : /* XXX: Crash avoidance. Need to work with reporter to figure out what goes wrong */
940 : if (rest < 0) rest = 0;
941 :
942 : if (rest) memmove(ctx->buf.c, start, rest);
943 : ctx->buf.len = rest;
944 : }
945 :
946 : char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen TSRMLS_DC)
947 : {
948 : smart_str surl = {0};
949 : smart_str buf = {0};
950 : smart_str url_app = {0};
951 :
952 : smart_str_setl(&surl, url, urllen);
953 :
954 : smart_str_appends(&url_app, name);
955 : smart_str_appendc(&url_app, '=');
956 : smart_str_appends(&url_app, value);
957 :
958 : append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output);
959 :
960 : smart_str_0(&buf);
961 : if (newlen) *newlen = buf.len;
962 :
963 : smart_str_free(&url_app);
964 :
965 : return buf.c;
966 : }
967 :
968 :
969 : static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_bool do_flush TSRMLS_DC)
970 : {
971 : url_adapt_state_ex_t *ctx;
972 : char *retval;
973 :
974 : ctx = &BG(url_adapt_state_ex);
975 :
976 : xx_mainloop(ctx, src, srclen TSRMLS_CC);
977 :
978 : *newlen = ctx->result.len;
979 : if (!ctx->result.c) {
980 : smart_str_appendl(&ctx->result, "", 0);
981 : }
982 : smart_str_0(&ctx->result);
983 : if (do_flush) {
984 : smart_str_appendl(&ctx->result, ctx->buf.c, ctx->buf.len);
985 : *newlen += ctx->buf.len;
986 : smart_str_free(&ctx->buf);
987 : }
988 : retval = ctx->result.c;
989 : ctx->result.c = NULL;
990 : ctx->result.len = 0;
991 : return retval;
992 : }
993 :
994 : int php_url_scanner_ex_activate(TSRMLS_D)
995 : {
996 : url_adapt_state_ex_t *ctx;
997 :
998 : ctx = &BG(url_adapt_state_ex);
999 :
1000 : memset(ctx, 0, ((size_t) &((url_adapt_state_ex_t *)0)->tags));
1001 :
1002 : return SUCCESS;
1003 : }
1004 :
1005 : int php_url_scanner_ex_deactivate(TSRMLS_D)
1006 : {
1007 : url_adapt_state_ex_t *ctx;
1008 :
1009 : ctx = &BG(url_adapt_state_ex);
1010 :
1011 : smart_str_free(&ctx->result);
1012 : smart_str_free(&ctx->buf);
1013 : smart_str_free(&ctx->tag);
1014 : smart_str_free(&ctx->arg);
1015 :
1016 : return SUCCESS;
1017 : }
1018 :
1019 : static void php_url_scanner_output_handler(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
1020 : {
1021 : size_t len;
1022 :
1023 : if (BG(url_adapt_state_ex).url_app.len != 0) {
1024 : *handled_output = url_adapt_ext(output, output_len, &len, (zend_bool) (mode & PHP_OUTPUT_HANDLER_END ? 1 : 0) TSRMLS_CC);
1025 : if (sizeof(uint) < sizeof(size_t)) {
1026 : if (len > UINT_MAX)
1027 : len = UINT_MAX;
1028 : }
1029 : *handled_output_len = len;
1030 : } else if (BG(url_adapt_state_ex).url_app.len == 0) {
1031 : url_adapt_state_ex_t *ctx = &BG(url_adapt_state_ex);
1032 : if (ctx->buf.len) {
1033 : smart_str_appendl(&ctx->result, ctx->buf.c, ctx->buf.len);
1034 : smart_str_appendl(&ctx->result, output, output_len);
1035 :
1036 : *handled_output = ctx->result.c;
1037 : *handled_output_len = ctx->buf.len + output_len;
1038 :
1039 : ctx->result.c = NULL;
1040 : ctx->result.len = 0;
1041 : smart_str_free(&ctx->buf);
1042 : } else {
1043 : *handled_output = NULL;
1044 : }
1045 : } else {
1046 : *handled_output = NULL;
1047 : }
1048 : }
1049 :
1050 : int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC)
1051 : {
1052 : char *encoded;
1053 : int encoded_len;
1054 : smart_str val;
1055 :
1056 : if (! BG(url_adapt_state_ex).active) {
1057 : php_url_scanner_ex_activate(TSRMLS_C);
1058 : php_ob_set_internal_handler(php_url_scanner_output_handler, 0, "URL-Rewriter", 1 TSRMLS_CC);
1059 : BG(url_adapt_state_ex).active = 1;
1060 : }
1061 :
1062 :
1063 : if (BG(url_adapt_state_ex).url_app.len != 0) {
1064 : smart_str_appends(&BG(url_adapt_state_ex).url_app, PG(arg_separator).output);
1065 : }
1066 :
1067 : if (urlencode) {
1068 : encoded = php_url_encode(value, value_len, &encoded_len);
1069 : smart_str_setl(&val, encoded, encoded_len);
1070 : } else {
1071 : smart_str_setl(&val, value, value_len);
1072 : }
1073 :
1074 : smart_str_appendl(&BG(url_adapt_state_ex).url_app, name, name_len);
1075 : smart_str_appendc(&BG(url_adapt_state_ex).url_app, '=');
1076 : smart_str_append(&BG(url_adapt_state_ex).url_app, &val);
1077 :
1078 : smart_str_appends(&BG(url_adapt_state_ex).form_app, "<input type=\"hidden\" name=\"");
1079 : smart_str_appendl(&BG(url_adapt_state_ex).form_app, name, name_len);
1080 : smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" value=\"");
1081 : smart_str_append(&BG(url_adapt_state_ex).form_app, &val);
1082 : smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" />");
1083 :
1084 : if (urlencode)
1085 : efree(encoded);
1086 :
1087 : return SUCCESS;
1088 : }
1089 :
1090 : int php_url_scanner_reset_vars(TSRMLS_D)
1091 : {
1092 : BG(url_adapt_state_ex).form_app.len = 0;
1093 : BG(url_adapt_state_ex).url_app.len = 0;
1094 :
1095 : return SUCCESS;
1096 : }
1097 :
1098 : PHP_MINIT_FUNCTION(url_scanner)
1099 : {
1100 : BG(url_adapt_state_ex).tags = NULL;
1101 :
1102 : BG(url_adapt_state_ex).form_app.c = BG(url_adapt_state_ex).url_app.c = 0;
1103 : BG(url_adapt_state_ex).form_app.len = BG(url_adapt_state_ex).url_app.len = 0;
1104 :
1105 : REGISTER_INI_ENTRIES();
1106 : return SUCCESS;
1107 : }
1108 :
1109 : PHP_MSHUTDOWN_FUNCTION(url_scanner)
1110 : {
1111 : UNREGISTER_INI_ENTRIES();
1112 :
1113 : return SUCCESS;
1114 : }
1115 :
1116 : PHP_RINIT_FUNCTION(url_scanner)
1117 : {
1118 : BG(url_adapt_state_ex).active = 0;
1119 :
1120 : return SUCCESS;
1121 : }
1122 :
1123 : PHP_RSHUTDOWN_FUNCTION(url_scanner)
1124 : {
1125 : if (BG(url_adapt_state_ex).active) {
1126 : php_url_scanner_ex_deactivate(TSRMLS_C);
1127 : BG(url_adapt_state_ex).active = 0;
1128 : }
1129 :
1130 : smart_str_free(&BG(url_adapt_state_ex).form_app);
1131 : smart_str_free(&BG(url_adapt_state_ex).url_app);
1132 :
1133 : return SUCCESS;
1134 : }
|