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