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