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