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