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-2015 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 yy36;
550 if (yych <= '\v') goto yy32;
551 goto yy36;
552 } else {
553 if (yych <= '\r') goto yy32;
554 if (yych == ' ') goto yy32;
555 goto yy36;
556 }
557 } else {
558 if (yych <= '@') {
559 if (yych <= '/') goto yy28;
560 if (yych == '>') goto yy30;
561 goto yy36;
562 } else {
563 if (yych <= 'Z') goto yy34;
564 if (yych <= '`') goto yy36;
565 if (yych <= 'z') goto yy34;
566 goto yy36;
567 }
568 }
569 yy28:
570 ++YYCURSOR;
571 if ((yych = *YYCURSOR) == '>') goto yy39;
572 yy29:
573 #line 323 "ext/standard/url_scanner_ex.re"
574 { passthru(STD_ARGS); goto state_plain_begin; }
575 #line 576 "ext/standard/url_scanner_ex.c"
576 yy30:
577 ++YYCURSOR;
578 yy31:
579 #line 320 "ext/standard/url_scanner_ex.re"
580 { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
581 #line 582 "ext/standard/url_scanner_ex.c"
582 yy32:
583 ++YYCURSOR;
584 yych = *YYCURSOR;
585 goto yy38;
586 yy33:
587 #line 321 "ext/standard/url_scanner_ex.re"
588 { passthru(STD_ARGS); goto state_next_arg; }
589 #line 590 "ext/standard/url_scanner_ex.c"
590 yy34:
591 ++YYCURSOR;
592 #line 322 "ext/standard/url_scanner_ex.re"
593 { --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
594 #line 595 "ext/standard/url_scanner_ex.c"
595 yy36:
596 yych = *++YYCURSOR;
597 goto yy29;
598 yy37:
599 ++YYCURSOR;
600 if (YYLIMIT <= YYCURSOR) YYFILL(1);
601 yych = *YYCURSOR;
602 yy38:
603 if (yybm[0+yych] & 128) {
604 goto yy37;
605 }
606 goto yy33;
607 yy39:
608 ++YYCURSOR;
609 yych = *YYCURSOR;
610 goto yy31;
611 }
612 #line 324 "ext/standard/url_scanner_ex.re"
613
614
615 state_arg:
616 start = YYCURSOR;
617
618 #line 619 "ext/standard/url_scanner_ex.c"
619 {
620 YYCTYPE yych;
621 static const unsigned char yybm[] = {
622 0, 0, 0, 0, 0, 0, 0, 0,
623 0, 0, 0, 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, 128, 0, 0,
628 0, 0, 0, 0, 0, 0, 0, 0,
629 0, 0, 0, 0, 0, 0, 0, 0,
630 0, 128, 128, 128, 128, 128, 128, 128,
631 128, 128, 128, 128, 128, 128, 128, 128,
632 128, 128, 128, 128, 128, 128, 128, 128,
633 128, 128, 128, 0, 0, 0, 0, 0,
634 0, 128, 128, 128, 128, 128, 128, 128,
635 128, 128, 128, 128, 128, 128, 128, 128,
636 128, 128, 128, 128, 128, 128, 128, 128,
637 128, 128, 128, 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 0, 0, 0, 0, 0, 0, 0, 0,
642 0, 0, 0, 0, 0, 0, 0, 0,
643 0, 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 };
655 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
656 yych = *YYCURSOR;
657 if (yych <= '@') goto yy44;
658 if (yych <= 'Z') goto yy42;
659 if (yych <= '`') goto yy44;
660 if (yych >= '{') goto yy44;
661 yy42:
662 ++YYCURSOR;
663 yych = *YYCURSOR;
664 goto yy47;
665 yy43:
666 #line 329 "ext/standard/url_scanner_ex.re"
667 { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
668 #line 669 "ext/standard/url_scanner_ex.c"
669 yy44:
670 ++YYCURSOR;
671 #line 330 "ext/standard/url_scanner_ex.re"
672 { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
673 #line 674 "ext/standard/url_scanner_ex.c"
674 yy46:
675 ++YYCURSOR;
676 if (YYLIMIT <= YYCURSOR) YYFILL(1);
677 yych = *YYCURSOR;
678 yy47:
679 if (yybm[0+yych] & 128) {
680 goto yy46;
681 }
682 goto yy43;
683 }
684 #line 331 "ext/standard/url_scanner_ex.re"
685
686
687 state_before_val:
688 start = YYCURSOR;
689
690 #line 691 "ext/standard/url_scanner_ex.c"
691 {
692 YYCTYPE yych;
693 static const unsigned char yybm[] = {
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 128, 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 0, 0, 0, 0, 0, 0, 0, 0,
714 0, 0, 0, 0, 0, 0, 0, 0,
715 0, 0, 0, 0, 0, 0, 0, 0,
716 0, 0, 0, 0, 0, 0, 0, 0,
717 0, 0, 0, 0, 0, 0, 0, 0,
718 0, 0, 0, 0, 0, 0, 0, 0,
719 0, 0, 0, 0, 0, 0, 0, 0,
720 0, 0, 0, 0, 0, 0, 0, 0,
721 0, 0, 0, 0, 0, 0, 0, 0,
722 0, 0, 0, 0, 0, 0, 0, 0,
723 0, 0, 0, 0, 0, 0, 0, 0,
724 0, 0, 0, 0, 0, 0, 0, 0,
725 0, 0, 0, 0, 0, 0, 0, 0,
726 };
727 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
728 yych = *YYCURSOR;
729 if (yych == ' ') goto yy50;
730 if (yych == '=') goto yy52;
731 goto yy54;
732 yy50:
733 yych = *(YYMARKER = ++YYCURSOR);
734 if (yych == ' ') goto yy57;
735 if (yych == '=') goto yy55;
736 yy51:
737 #line 337 "ext/standard/url_scanner_ex.re"
738 { --YYCURSOR; goto state_next_arg_begin; }
739 #line 740 "ext/standard/url_scanner_ex.c"
740 yy52:
741 ++YYCURSOR;
742 yych = *YYCURSOR;
743 goto yy56;
744 yy53:
745 #line 336 "ext/standard/url_scanner_ex.re"
746 { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
747 #line 748 "ext/standard/url_scanner_ex.c"
748 yy54:
749 yych = *++YYCURSOR;
750 goto yy51;
751 yy55:
752 ++YYCURSOR;
753 if (YYLIMIT <= YYCURSOR) YYFILL(1);
754 yych = *YYCURSOR;
755 yy56:
756 if (yybm[0+yych] & 128) {
757 goto yy55;
758 }
759 goto yy53;
760 yy57:
761 ++YYCURSOR;
762 if (YYLIMIT <= YYCURSOR) YYFILL(1);
763 yych = *YYCURSOR;
764 if (yych == ' ') goto yy57;
765 if (yych == '=') goto yy55;
766 YYCURSOR = YYMARKER;
767 goto yy51;
768 }
769 #line 338 "ext/standard/url_scanner_ex.re"
770
771
772
773 state_val:
774 start = YYCURSOR;
775
776 #line 777 "ext/standard/url_scanner_ex.c"
777 {
778 YYCTYPE yych;
779 static const unsigned char yybm[] = {
780 224, 224, 224, 224, 224, 224, 224, 224,
781 224, 192, 192, 224, 224, 192, 224, 224,
782 224, 224, 224, 224, 224, 224, 224, 224,
783 224, 224, 224, 224, 224, 224, 224, 224,
784 192, 224, 64, 224, 224, 224, 224, 128,
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, 0, 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 224, 224, 224, 224, 224, 224, 224, 224,
800 224, 224, 224, 224, 224, 224, 224, 224,
801 224, 224, 224, 224, 224, 224, 224, 224,
802 224, 224, 224, 224, 224, 224, 224, 224,
803 224, 224, 224, 224, 224, 224, 224, 224,
804 224, 224, 224, 224, 224, 224, 224, 224,
805 224, 224, 224, 224, 224, 224, 224, 224,
806 224, 224, 224, 224, 224, 224, 224, 224,
807 224, 224, 224, 224, 224, 224, 224, 224,
808 224, 224, 224, 224, 224, 224, 224, 224,
809 224, 224, 224, 224, 224, 224, 224, 224,
810 224, 224, 224, 224, 224, 224, 224, 224,
811 224, 224, 224, 224, 224, 224, 224, 224,
812 };
813 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
814 yych = *YYCURSOR;
815 if (yych <= ' ') {
816 if (yych <= '\f') {
817 if (yych <= 0x08) goto yy65;
818 if (yych <= '\n') goto yy67;
819 goto yy65;
820 } else {
821 if (yych <= '\r') goto yy67;
822 if (yych <= 0x1F) goto yy65;
823 goto yy67;
824 }
825 } else {
826 if (yych <= '&') {
827 if (yych != '"') goto yy65;
828 } else {
829 if (yych <= '\'') goto yy64;
830 if (yych == '>') goto yy67;
831 goto yy65;
832 }
833 }
834 yych = *(YYMARKER = ++YYCURSOR);
835 if (yych != '>') goto yy76;
836 yy63:
837 #line 347 "ext/standard/url_scanner_ex.re"
838 { passthru(STD_ARGS); goto state_next_arg_begin; }
839 #line 840 "ext/standard/url_scanner_ex.c"
840 yy64:
841 yych = *(YYMARKER = ++YYCURSOR);
842 if (yych == '>') goto yy63;
843 goto yy71;
844 yy65:
845 ++YYCURSOR;
846 yych = *YYCURSOR;
847 goto yy69;
848 yy66:
849 #line 346 "ext/standard/url_scanner_ex.re"
850 { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
851 #line 852 "ext/standard/url_scanner_ex.c"
852 yy67:
853 yych = *++YYCURSOR;
854 goto yy63;
855 yy68:
856 ++YYCURSOR;
857 if (YYLIMIT <= YYCURSOR) YYFILL(1);
858 yych = *YYCURSOR;
859 yy69:
860 if (yybm[0+yych] & 32) {
861 goto yy68;
862 }
863 goto yy66;
864 yy70:
865 ++YYCURSOR;
866 if (YYLIMIT <= YYCURSOR) YYFILL(1);
867 yych = *YYCURSOR;
868 yy71:
869 if (yybm[0+yych] & 64) {
870 goto yy70;
871 }
872 if (yych <= '=') goto yy73;
873 yy72:
874 YYCURSOR = YYMARKER;
875 goto yy63;
876 yy73:
877 ++YYCURSOR;
878 #line 345 "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 yy75:
882 ++YYCURSOR;
883 if (YYLIMIT <= YYCURSOR) YYFILL(1);
884 yych = *YYCURSOR;
885 yy76:
886 if (yybm[0+yych] & 128) {
887 goto yy75;
888 }
889 if (yych >= '>') goto yy72;
890 ++YYCURSOR;
891 #line 344 "ext/standard/url_scanner_ex.re"
892 { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
893 #line 894 "ext/standard/url_scanner_ex.c"
894 }
895 #line 348 "ext/standard/url_scanner_ex.re"
896
897
898 stop:
899 rest = YYLIMIT - start;
900 scdebug(("stopped in state %d at pos %d (%d:%c) %d\n", STATE, YYCURSOR - ctx->buf.c, *YYCURSOR, *YYCURSOR, rest));
901 /* XXX: Crash avoidance. Need to work with reporter to figure out what goes wrong */
902 if (rest < 0) rest = 0;
903
904 if (rest) memmove(ctx->buf.c, start, rest);
905 ctx->buf.len = rest;
906 }
907
php_url_scanner_adapt_single_url(const char * url,size_t urllen,const char * name,const char * value,size_t * newlen TSRMLS_DC)908 char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen TSRMLS_DC)
909 {
910 smart_str surl = {0};
911 smart_str buf = {0};
912 smart_str url_app = {0};
913
914 smart_str_setl(&surl, url, urllen);
915
916 smart_str_appends(&url_app, name);
917 smart_str_appendc(&url_app, '=');
918 smart_str_appends(&url_app, value);
919
920 append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output);
921
922 smart_str_0(&buf);
923 if (newlen) *newlen = buf.len;
924
925 smart_str_free(&url_app);
926
927 return buf.c;
928 }
929
930
url_adapt_ext(const char * src,size_t srclen,size_t * newlen,zend_bool do_flush TSRMLS_DC)931 static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_bool do_flush TSRMLS_DC)
932 {
933 url_adapt_state_ex_t *ctx;
934 char *retval;
935
936 ctx = &BG(url_adapt_state_ex);
937
938 xx_mainloop(ctx, src, srclen TSRMLS_CC);
939
940 *newlen = ctx->result.len;
941 if (!ctx->result.c) {
942 smart_str_appendl(&ctx->result, "", 0);
943 }
944 smart_str_0(&ctx->result);
945 if (do_flush) {
946 smart_str_appendl(&ctx->result, ctx->buf.c, ctx->buf.len);
947 *newlen += ctx->buf.len;
948 smart_str_free(&ctx->buf);
949 }
950 retval = ctx->result.c;
951 ctx->result.c = NULL;
952 ctx->result.len = 0;
953 return retval;
954 }
955
php_url_scanner_ex_activate(TSRMLS_D)956 static int php_url_scanner_ex_activate(TSRMLS_D)
957 {
958 url_adapt_state_ex_t *ctx;
959
960 ctx = &BG(url_adapt_state_ex);
961
962 memset(ctx, 0, ((size_t) &((url_adapt_state_ex_t *)0)->tags));
963
964 return SUCCESS;
965 }
966
php_url_scanner_ex_deactivate(TSRMLS_D)967 static int php_url_scanner_ex_deactivate(TSRMLS_D)
968 {
969 url_adapt_state_ex_t *ctx;
970
971 ctx = &BG(url_adapt_state_ex);
972
973 smart_str_free(&ctx->result);
974 smart_str_free(&ctx->buf);
975 smart_str_free(&ctx->tag);
976 smart_str_free(&ctx->arg);
977
978 return SUCCESS;
979 }
980
php_url_scanner_output_handler(char * output,uint output_len,char ** handled_output,uint * handled_output_len,int mode TSRMLS_DC)981 static void php_url_scanner_output_handler(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC)
982 {
983 size_t len;
984
985 if (BG(url_adapt_state_ex).url_app.len != 0) {
986 *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);
987 if (sizeof(uint) < sizeof(size_t)) {
988 if (len > UINT_MAX)
989 len = UINT_MAX;
990 }
991 *handled_output_len = len;
992 } else if (BG(url_adapt_state_ex).url_app.len == 0) {
993 url_adapt_state_ex_t *ctx = &BG(url_adapt_state_ex);
994 if (ctx->buf.len) {
995 smart_str_appendl(&ctx->result, ctx->buf.c, ctx->buf.len);
996 smart_str_appendl(&ctx->result, output, output_len);
997
998 *handled_output = ctx->result.c;
999 *handled_output_len = ctx->buf.len + output_len;
1000
1001 ctx->result.c = NULL;
1002 ctx->result.len = 0;
1003 smart_str_free(&ctx->buf);
1004 } else {
1005 *handled_output = estrndup(output, *handled_output_len = output_len);
1006 }
1007 } else {
1008 *handled_output = NULL;
1009 }
1010 }
1011
php_url_scanner_add_var(char * name,int name_len,char * value,int value_len,int urlencode TSRMLS_DC)1012 PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC)
1013 {
1014 char *encoded = NULL;
1015 int encoded_len;
1016 smart_str val;
1017
1018 if (! BG(url_adapt_state_ex).active) {
1019 php_url_scanner_ex_activate(TSRMLS_C);
1020 php_output_start_internal(ZEND_STRL("URL-Rewriter"), php_url_scanner_output_handler, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
1021 BG(url_adapt_state_ex).active = 1;
1022 }
1023
1024
1025 if (BG(url_adapt_state_ex).url_app.len != 0) {
1026 smart_str_appends(&BG(url_adapt_state_ex).url_app, PG(arg_separator).output);
1027 }
1028
1029 if (urlencode) {
1030 encoded = php_url_encode(value, value_len, &encoded_len);
1031 smart_str_setl(&val, encoded, encoded_len);
1032 } else {
1033 smart_str_setl(&val, value, value_len);
1034 }
1035
1036 smart_str_appendl(&BG(url_adapt_state_ex).url_app, name, name_len);
1037 smart_str_appendc(&BG(url_adapt_state_ex).url_app, '=');
1038 smart_str_append(&BG(url_adapt_state_ex).url_app, &val);
1039
1040 smart_str_appends(&BG(url_adapt_state_ex).form_app, "<input type=\"hidden\" name=\"");
1041 smart_str_appendl(&BG(url_adapt_state_ex).form_app, name, name_len);
1042 smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" value=\"");
1043 smart_str_append(&BG(url_adapt_state_ex).form_app, &val);
1044 smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" />");
1045
1046 if (urlencode)
1047 efree(encoded);
1048
1049 return SUCCESS;
1050 }
1051
php_url_scanner_reset_vars(TSRMLS_D)1052 PHPAPI int php_url_scanner_reset_vars(TSRMLS_D)
1053 {
1054 BG(url_adapt_state_ex).form_app.len = 0;
1055 BG(url_adapt_state_ex).url_app.len = 0;
1056
1057 return SUCCESS;
1058 }
1059
PHP_MINIT_FUNCTION(url_scanner)1060 PHP_MINIT_FUNCTION(url_scanner)
1061 {
1062 BG(url_adapt_state_ex).tags = NULL;
1063
1064 BG(url_adapt_state_ex).form_app.c = BG(url_adapt_state_ex).url_app.c = 0;
1065 BG(url_adapt_state_ex).form_app.len = BG(url_adapt_state_ex).url_app.len = 0;
1066
1067 REGISTER_INI_ENTRIES();
1068 return SUCCESS;
1069 }
1070
PHP_MSHUTDOWN_FUNCTION(url_scanner)1071 PHP_MSHUTDOWN_FUNCTION(url_scanner)
1072 {
1073 UNREGISTER_INI_ENTRIES();
1074
1075 return SUCCESS;
1076 }
1077
PHP_RINIT_FUNCTION(url_scanner)1078 PHP_RINIT_FUNCTION(url_scanner)
1079 {
1080 BG(url_adapt_state_ex).active = 0;
1081
1082 return SUCCESS;
1083 }
1084
PHP_RSHUTDOWN_FUNCTION(url_scanner)1085 PHP_RSHUTDOWN_FUNCTION(url_scanner)
1086 {
1087 if (BG(url_adapt_state_ex).active) {
1088 php_url_scanner_ex_deactivate(TSRMLS_C);
1089 BG(url_adapt_state_ex).active = 0;
1090 }
1091
1092 smart_str_free(&BG(url_adapt_state_ex).form_app);
1093 smart_str_free(&BG(url_adapt_state_ex).url_app);
1094
1095 return SUCCESS;
1096 }
1097