xref: /PHP-7.0/ext/standard/url_scanner_ex.c (revision cf3ef363)
1 /* Generated by re2c 0.16 */
2 #line 1 "ext/standard/url_scanner_ex.re"
3 /*
4   +----------------------------------------------------------------------+
5   | PHP Version 7                                                        |
6   +----------------------------------------------------------------------+
7   | Copyright (c) 1997-2017 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 #include "php_string.h"
39 #define STATE_TAG SOME_OTHER_STATE_TAG
40 #include "basic_functions.h"
41 #include "url.h"
42 #undef STATE_TAG
43 
44 #define url_scanner url_scanner_ex
45 
46 #include "zend_smart_str.h"
47 
tag_dtor(zval * zv)48 static void tag_dtor(zval *zv)
49 {
50 	free(Z_PTR_P(zv));
51 }
52 
PHP_INI_MH(OnUpdateTags)53 static PHP_INI_MH(OnUpdateTags)
54 {
55 	url_adapt_state_ex_t *ctx;
56 	char *key;
57 	char *tmp;
58 	char *lasts = NULL;
59 
60 	ctx = &BG(url_adapt_state_ex);
61 
62 	tmp = estrndup(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
63 
64 	if (ctx->tags)
65 		zend_hash_destroy(ctx->tags);
66 	else {
67 		ctx->tags = malloc(sizeof(HashTable));
68 		if (!ctx->tags) {
69 			return FAILURE;
70 		}
71 	}
72 
73 	zend_hash_init(ctx->tags, 0, NULL, tag_dtor, 1);
74 
75 	for (key = php_strtok_r(tmp, ",", &lasts);
76 			key;
77 			key = php_strtok_r(NULL, ",", &lasts)) {
78 		char *val;
79 
80 		val = strchr(key, '=');
81 		if (val) {
82 			char *q;
83 			size_t keylen;
84 
85 			*val++ = '\0';
86 			for (q = key; *q; q++)
87 				*q = tolower(*q);
88 			keylen = q - key;
89 			/* key is stored withOUT NUL
90 			   val is stored WITH    NUL */
91 			zend_hash_str_add_mem(ctx->tags, key, keylen, val, strlen(val)+1);
92 		}
93 	}
94 
95 	efree(tmp);
96 
97 	return SUCCESS;
98 }
99 
100 PHP_INI_BEGIN()
101 	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()102 PHP_INI_END()
103 
104 #line 108 "ext/standard/url_scanner_ex.re"
105 
106 
107 #define YYFILL(n) goto done
108 #define YYCTYPE unsigned char
109 #define YYCURSOR p
110 #define YYLIMIT q
111 #define YYMARKER r
112 
113 static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator)
114 {
115 	register const char *p, *q;
116 	const char *bash = NULL;
117 	const char *sep = "?";
118 
119 	/*
120 	 * Don't modify "//example.com" full path, unless
121 	 * HTTP_HOST matches.
122 	 */
123 	if (ZSTR_LEN(url->s) > 2 && ZSTR_VAL(url->s)[0] == '/' && ZSTR_VAL(url->s)[1] == '/') {
124 		const char *end_chars = "/\"'?>\r\n";
125 		zval *tmp = NULL, *http_host = NULL;
126 		size_t target_len, host_len;
127 		if ((!(tmp = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_SERVER"))))
128 			|| Z_TYPE_P(tmp) != IS_ARRAY
129 			|| !(http_host = zend_hash_str_find(HASH_OF(tmp), ZEND_STRL("HTTP_HOST")))
130 			|| Z_TYPE_P(http_host) != IS_STRING) {
131 			smart_str_append_smart_str(dest, url);
132 			return;
133 		}
134 
135 		/* HTTP_HOST could be "example.com:8888", etc. */
136 		/* Need to find end of URL in buffer */
137 		host_len   = strcspn(Z_STRVAL_P(http_host), ":");
138 		target_len = php_strcspn(
139 			ZSTR_VAL(url->s) + 2, (char *) end_chars,
140 			ZSTR_VAL(url->s) + ZSTR_LEN(url->s), (char *) end_chars + strlen(end_chars));
141 		if (host_len
142 			&& host_len == target_len
143 			&& strncasecmp(Z_STRVAL_P(http_host), ZSTR_VAL(url->s)+2, host_len)) {
144 			smart_str_append_smart_str(dest, url);
145 			return;
146 		}
147 	}
148 
149 	q = (p = ZSTR_VAL(url->s)) + ZSTR_LEN(url->s);
150 
151 scan:
152 
153 #line 154 "ext/standard/url_scanner_ex.c"
154 {
155 	YYCTYPE yych;
156 	static const unsigned char yybm[] = {
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,   0, 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,   0, 128, 128, 128, 128,   0,
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 		128, 128, 128, 128, 128, 128, 128, 128,
180 		128, 128, 128, 128, 128, 128, 128, 128,
181 		128, 128, 128, 128, 128, 128, 128, 128,
182 		128, 128, 128, 128, 128, 128, 128, 128,
183 		128, 128, 128, 128, 128, 128, 128, 128,
184 		128, 128, 128, 128, 128, 128, 128, 128,
185 		128, 128, 128, 128, 128, 128, 128, 128,
186 		128, 128, 128, 128, 128, 128, 128, 128,
187 		128, 128, 128, 128, 128, 128, 128, 128,
188 		128, 128, 128, 128, 128, 128, 128, 128,
189 	};
190 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
191 	yych = *YYCURSOR;
192 	if (yybm[0+yych] & 128) {
193 		goto yy2;
194 	}
195 	if (yych <= '#') goto yy5;
196 	if (yych <= ':') goto yy7;
197 	goto yy9;
198 yy2:
199 	++YYCURSOR;
200 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
201 	yych = *YYCURSOR;
202 	if (yybm[0+yych] & 128) {
203 		goto yy2;
204 	}
205 #line 159 "ext/standard/url_scanner_ex.re"
206 	{ goto scan; }
207 #line 208 "ext/standard/url_scanner_ex.c"
208 yy5:
209 	++YYCURSOR;
210 #line 158 "ext/standard/url_scanner_ex.re"
211 	{ bash = p - 1; goto done; }
212 #line 213 "ext/standard/url_scanner_ex.c"
213 yy7:
214 	++YYCURSOR;
215 #line 156 "ext/standard/url_scanner_ex.re"
216 	{ smart_str_append_smart_str(dest, url); return; }
217 #line 218 "ext/standard/url_scanner_ex.c"
218 yy9:
219 	++YYCURSOR;
220 #line 157 "ext/standard/url_scanner_ex.re"
221 	{ sep = separator; goto scan; }
222 #line 223 "ext/standard/url_scanner_ex.c"
223 }
224 #line 160 "ext/standard/url_scanner_ex.re"
225 
226 done:
227 
228 	/* Don't modify URLs of the format "#mark" */
229 	if (bash && bash - ZSTR_VAL(url->s) == 0) {
230 		smart_str_append_smart_str(dest, url);
231 		return;
232 	}
233 
234 	if (bash)
235 		smart_str_appendl(dest, ZSTR_VAL(url->s), bash - ZSTR_VAL(url->s));
236 	else
237 		smart_str_append_smart_str(dest, url);
238 
239 	smart_str_appends(dest, sep);
240 	smart_str_append_smart_str(dest, url_app);
241 
242 	if (bash)
243 		smart_str_appendl(dest, bash, q - bash);
244 }
245 
246 
247 #undef YYFILL
248 #undef YYCTYPE
249 #undef YYCURSOR
250 #undef YYLIMIT
251 #undef YYMARKER
252 
tag_arg(url_adapt_state_ex_t * ctx,char quotes,char type)253 static inline void tag_arg(url_adapt_state_ex_t *ctx, char quotes, char type)
254 {
255 	char f = 0;
256 
257 	if (strncasecmp(ZSTR_VAL(ctx->arg.s), ctx->lookup_data, ZSTR_LEN(ctx->arg.s)) == 0)
258 		f = 1;
259 
260 	if (quotes)
261 		smart_str_appendc(&ctx->result, type);
262 	if (f) {
263 		append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output);
264 	} else {
265 		smart_str_append_smart_str(&ctx->result, &ctx->val);
266 	}
267 	if (quotes)
268 		smart_str_appendc(&ctx->result, type);
269 }
270 
271 enum {
272 	STATE_PLAIN = 0,
273 	STATE_TAG,
274 	STATE_NEXT_ARG,
275 	STATE_ARG,
276 	STATE_BEFORE_VAL,
277 	STATE_VAL
278 };
279 
280 #define YYFILL(n) goto stop
281 #define YYCTYPE unsigned char
282 #define YYCURSOR xp
283 #define YYLIMIT end
284 #define YYMARKER q
285 #define STATE ctx->state
286 
287 #define STD_PARA url_adapt_state_ex_t *ctx, char *start, char *YYCURSOR
288 #define STD_ARGS ctx, start, xp
289 
290 #if SCANNER_DEBUG
291 #define scdebug(x) printf x
292 #else
293 #define scdebug(x)
294 #endif
295 
passthru(STD_PARA)296 static inline void passthru(STD_PARA)
297 {
298 	scdebug(("appending %d chars, starting with %c\n", YYCURSOR-start, *start));
299 	smart_str_appendl(&ctx->result, start, YYCURSOR - start);
300 }
301 
302 /*
303  * This function appends a hidden input field after a <form> or
304  * <fieldset>.  The latter is important for XHTML.
305  */
306 
handle_form(STD_PARA)307 static void handle_form(STD_PARA)
308 {
309 	int doit = 0;
310 
311 	if (ZSTR_LEN(ctx->form_app.s) > 0) {
312 		switch (ZSTR_LEN(ctx->tag.s)) {
313 			case sizeof("form") - 1:
314 				if (!strncasecmp(ZSTR_VAL(ctx->tag.s), "form", sizeof("form") - 1)) {
315 					doit = 1;
316 				}
317 				if (doit && ctx->val.s && ctx->lookup_data && *ctx->lookup_data) {
318 					char *e, *p = (char *)zend_memnstr(ZSTR_VAL(ctx->val.s), "://", sizeof("://") - 1, ZSTR_VAL(ctx->val.s) + ZSTR_LEN(ctx->val.s));
319 					if (p) {
320 						e = memchr(p, '/', (ZSTR_VAL(ctx->val.s) + ZSTR_LEN(ctx->val.s)) - p);
321 						if (!e) {
322 							e = ZSTR_VAL(ctx->val.s) + ZSTR_LEN(ctx->val.s);
323 						}
324 						if ((e - p) && strncasecmp(p, ctx->lookup_data, (e - p))) {
325 							doit = 0;
326 						}
327 					}
328 				}
329 				break;
330 
331 			case sizeof("fieldset") - 1:
332 				if (!strncasecmp(ZSTR_VAL(ctx->tag.s), "fieldset", sizeof("fieldset") - 1)) {
333 					doit = 1;
334 				}
335 				break;
336 		}
337 
338 		if (doit)
339 			smart_str_append_smart_str(&ctx->result, &ctx->form_app);
340 	}
341 }
342 
343 /*
344  *  HANDLE_TAG copies the HTML Tag and checks whether we
345  *  have that tag in our table. If we might modify it,
346  *  we continue to scan the tag, otherwise we simply copy the complete
347  *  HTML stuff to the result buffer.
348  */
349 
handle_tag(STD_PARA)350 static inline void handle_tag(STD_PARA)
351 {
352 	int ok = 0;
353 	unsigned int i;
354 
355 	if (ctx->tag.s) {
356 		ZSTR_LEN(ctx->tag.s) = 0;
357 	}
358 	smart_str_appendl(&ctx->tag, start, YYCURSOR - start);
359 	for (i = 0; i < ZSTR_LEN(ctx->tag.s); i++)
360 		ZSTR_VAL(ctx->tag.s)[i] = tolower((int)(unsigned char)ZSTR_VAL(ctx->tag.s)[i]);
361     /* intentionally using str_find here, in case the hash value is set, but the string val is changed later */
362 	if ((ctx->lookup_data = zend_hash_str_find_ptr(ctx->tags, ZSTR_VAL(ctx->tag.s), ZSTR_LEN(ctx->tag.s))) != NULL)
363 		ok = 1;
364 	STATE = ok ? STATE_NEXT_ARG : STATE_PLAIN;
365 }
366 
handle_arg(STD_PARA)367 static inline void handle_arg(STD_PARA)
368 {
369 	if (ctx->arg.s) {
370 		ZSTR_LEN(ctx->arg.s) = 0;
371 	}
372 	smart_str_appendl(&ctx->arg, start, YYCURSOR - start);
373 }
374 
handle_val(STD_PARA,char quotes,char type)375 static inline void handle_val(STD_PARA, char quotes, char type)
376 {
377 	smart_str_setl(&ctx->val, start + quotes, YYCURSOR - start - quotes * 2);
378 	tag_arg(ctx, quotes, type);
379 }
380 
xx_mainloop(url_adapt_state_ex_t * ctx,const char * newdata,size_t newlen)381 static inline void xx_mainloop(url_adapt_state_ex_t *ctx, const char *newdata, size_t newlen)
382 {
383 	char *end, *q;
384 	char *xp;
385 	char *start;
386 	size_t rest;
387 
388 	smart_str_appendl(&ctx->buf, newdata, newlen);
389 
390 	YYCURSOR = ZSTR_VAL(ctx->buf.s);
391 	YYLIMIT = ZSTR_VAL(ctx->buf.s) + ZSTR_LEN(ctx->buf.s);
392 
393 	switch (STATE) {
394 		case STATE_PLAIN: goto state_plain;
395 		case STATE_TAG: goto state_tag;
396 		case STATE_NEXT_ARG: goto state_next_arg;
397 		case STATE_ARG: goto state_arg;
398 		case STATE_BEFORE_VAL: goto state_before_val;
399 		case STATE_VAL: goto state_val;
400 	}
401 
402 
403 state_plain_begin:
404 	STATE = STATE_PLAIN;
405 
406 state_plain:
407 	start = YYCURSOR;
408 
409 #line 410 "ext/standard/url_scanner_ex.c"
410 {
411 	YYCTYPE yych;
412 	static const unsigned char yybm[] = {
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,   0, 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 		128, 128, 128, 128, 128, 128, 128, 128,
430 		128, 128, 128, 128, 128, 128, 128, 128,
431 		128, 128, 128, 128, 128, 128, 128, 128,
432 		128, 128, 128, 128, 128, 128, 128, 128,
433 		128, 128, 128, 128, 128, 128, 128, 128,
434 		128, 128, 128, 128, 128, 128, 128, 128,
435 		128, 128, 128, 128, 128, 128, 128, 128,
436 		128, 128, 128, 128, 128, 128, 128, 128,
437 		128, 128, 128, 128, 128, 128, 128, 128,
438 		128, 128, 128, 128, 128, 128, 128, 128,
439 		128, 128, 128, 128, 128, 128, 128, 128,
440 		128, 128, 128, 128, 128, 128, 128, 128,
441 		128, 128, 128, 128, 128, 128, 128, 128,
442 		128, 128, 128, 128, 128, 128, 128, 128,
443 		128, 128, 128, 128, 128, 128, 128, 128,
444 		128, 128, 128, 128, 128, 128, 128, 128,
445 	};
446 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
447 	yych = *YYCURSOR;
448 	if (yybm[0+yych] & 128) {
449 		goto yy13;
450 	}
451 	goto yy16;
452 yy13:
453 	++YYCURSOR;
454 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
455 	yych = *YYCURSOR;
456 	if (yybm[0+yych] & 128) {
457 		goto yy13;
458 	}
459 #line 345 "ext/standard/url_scanner_ex.re"
460 	{ passthru(STD_ARGS); goto state_plain; }
461 #line 462 "ext/standard/url_scanner_ex.c"
462 yy16:
463 	++YYCURSOR;
464 #line 344 "ext/standard/url_scanner_ex.re"
465 	{ passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
466 #line 467 "ext/standard/url_scanner_ex.c"
467 }
468 #line 346 "ext/standard/url_scanner_ex.re"
469 
470 
471 state_tag:
472 	start = YYCURSOR;
473 
474 #line 475 "ext/standard/url_scanner_ex.c"
475 {
476 	YYCTYPE yych;
477 	static const unsigned char yybm[] = {
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, 128,   0,   0,   0,   0,   0,
486 		  0, 128, 128, 128, 128, 128, 128, 128,
487 		128, 128, 128, 128, 128, 128, 128, 128,
488 		128, 128, 128, 128, 128, 128, 128, 128,
489 		128, 128, 128,   0,   0,   0,   0,   0,
490 		  0, 128, 128, 128, 128, 128, 128, 128,
491 		128, 128, 128, 128, 128, 128, 128, 128,
492 		128, 128, 128, 128, 128, 128, 128, 128,
493 		128, 128, 128,   0,   0,   0,   0,   0,
494 		  0,   0,   0,   0,   0,   0,   0,   0,
495 		  0,   0,   0,   0,   0,   0,   0,   0,
496 		  0,   0,   0,   0,   0,   0,   0,   0,
497 		  0,   0,   0,   0,   0,   0,   0,   0,
498 		  0,   0,   0,   0,   0,   0,   0,   0,
499 		  0,   0,   0,   0,   0,   0,   0,   0,
500 		  0,   0,   0,   0,   0,   0,   0,   0,
501 		  0,   0,   0,   0,   0,   0,   0,   0,
502 		  0,   0,   0,   0,   0,   0,   0,   0,
503 		  0,   0,   0,   0,   0,   0,   0,   0,
504 		  0,   0,   0,   0,   0,   0,   0,   0,
505 		  0,   0,   0,   0,   0,   0,   0,   0,
506 		  0,   0,   0,   0,   0,   0,   0,   0,
507 		  0,   0,   0,   0,   0,   0,   0,   0,
508 		  0,   0,   0,   0,   0,   0,   0,   0,
509 		  0,   0,   0,   0,   0,   0,   0,   0,
510 	};
511 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
512 	yych = *YYCURSOR;
513 	if (yybm[0+yych] & 128) {
514 		goto yy22;
515 	}
516 	++YYCURSOR;
517 #line 352 "ext/standard/url_scanner_ex.re"
518 	{ passthru(STD_ARGS); goto state_plain_begin; }
519 #line 520 "ext/standard/url_scanner_ex.c"
520 yy22:
521 	++YYCURSOR;
522 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
523 	yych = *YYCURSOR;
524 	if (yybm[0+yych] & 128) {
525 		goto yy22;
526 	}
527 #line 351 "ext/standard/url_scanner_ex.re"
528 	{ handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; }
529 #line 530 "ext/standard/url_scanner_ex.c"
530 }
531 #line 353 "ext/standard/url_scanner_ex.re"
532 
533 
534 state_next_arg_begin:
535 	STATE = STATE_NEXT_ARG;
536 
537 state_next_arg:
538 	start = YYCURSOR;
539 
540 #line 541 "ext/standard/url_scanner_ex.c"
541 {
542 	YYCTYPE yych;
543 	static const unsigned char yybm[] = {
544 		  0,   0,   0,   0,   0,   0,   0,   0,
545 		  0, 128, 128, 128,   0, 128,   0,   0,
546 		  0,   0,   0,   0,   0,   0,   0,   0,
547 		  0,   0,   0,   0,   0,   0,   0,   0,
548 		128,   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 		  0,   0,   0,   0,   0,   0,   0,   0,
571 		  0,   0,   0,   0,   0,   0,   0,   0,
572 		  0,   0,   0,   0,   0,   0,   0,   0,
573 		  0,   0,   0,   0,   0,   0,   0,   0,
574 		  0,   0,   0,   0,   0,   0,   0,   0,
575 		  0,   0,   0,   0,   0,   0,   0,   0,
576 	};
577 	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
578 	yych = *YYCURSOR;
579 	if (yybm[0+yych] & 128) {
580 		goto yy29;
581 	}
582 	if (yych <= '>') {
583 		if (yych == '/') goto yy32;
584 		if (yych >= '>') goto yy33;
585 	} else {
586 		if (yych <= 'Z') {
587 			if (yych >= 'A') goto yy35;
588 		} else {
589 			if (yych <= '`') goto yy27;
590 			if (yych <= 'z') goto yy35;
591 		}
592 	}
593 yy27:
594 	++YYCURSOR;
595 yy28:
596 #line 364 "ext/standard/url_scanner_ex.re"
597 	{ passthru(STD_ARGS); goto state_plain_begin; }
598 #line 599 "ext/standard/url_scanner_ex.c"
599 yy29:
600 	++YYCURSOR;
601 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
602 	yych = *YYCURSOR;
603 	if (yybm[0+yych] & 128) {
604 		goto yy29;
605 	}
606 #line 362 "ext/standard/url_scanner_ex.re"
607 	{ passthru(STD_ARGS); goto state_next_arg; }
608 #line 609 "ext/standard/url_scanner_ex.c"
609 yy32:
610 	yych = *++YYCURSOR;
611 	if (yych != '>') goto yy28;
612 yy33:
613 	++YYCURSOR;
614 #line 361 "ext/standard/url_scanner_ex.re"
615 	{ passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
616 #line 617 "ext/standard/url_scanner_ex.c"
617 yy35:
618 	++YYCURSOR;
619 #line 363 "ext/standard/url_scanner_ex.re"
620 	{ --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
621 #line 622 "ext/standard/url_scanner_ex.c"
622 }
623 #line 365 "ext/standard/url_scanner_ex.re"
624 
625 
626 state_arg:
627 	start = YYCURSOR;
628 
629 #line 630 "ext/standard/url_scanner_ex.c"
630 {
631 	YYCTYPE yych;
632 	static const unsigned char yybm[] = {
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, 128,   0,   0,
639 		  0,   0,   0,   0,   0,   0,   0,   0,
640 		  0,   0,   0,   0,   0,   0,   0,   0,
641 		  0, 128, 128, 128, 128, 128, 128, 128,
642 		128, 128, 128, 128, 128, 128, 128, 128,
643 		128, 128, 128, 128, 128, 128, 128, 128,
644 		128, 128, 128,   0,   0,   0,   0,   0,
645 		  0, 128, 128, 128, 128, 128, 128, 128,
646 		128, 128, 128, 128, 128, 128, 128, 128,
647 		128, 128, 128, 128, 128, 128, 128, 128,
648 		128, 128, 128,   0,   0,   0,   0,   0,
649 		  0,   0,   0,   0,   0,   0,   0,   0,
650 		  0,   0,   0,   0,   0,   0,   0,   0,
651 		  0,   0,   0,   0,   0,   0,   0,   0,
652 		  0,   0,   0,   0,   0,   0,   0,   0,
653 		  0,   0,   0,   0,   0,   0,   0,   0,
654 		  0,   0,   0,   0,   0,   0,   0,   0,
655 		  0,   0,   0,   0,   0,   0,   0,   0,
656 		  0,   0,   0,   0,   0,   0,   0,   0,
657 		  0,   0,   0,   0,   0,   0,   0,   0,
658 		  0,   0,   0,   0,   0,   0,   0,   0,
659 		  0,   0,   0,   0,   0,   0,   0,   0,
660 		  0,   0,   0,   0,   0,   0,   0,   0,
661 		  0,   0,   0,   0,   0,   0,   0,   0,
662 		  0,   0,   0,   0,   0,   0,   0,   0,
663 		  0,   0,   0,   0,   0,   0,   0,   0,
664 		  0,   0,   0,   0,   0,   0,   0,   0,
665 	};
666 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
667 	yych = *YYCURSOR;
668 	if (yych <= '@') goto yy39;
669 	if (yych <= 'Z') goto yy41;
670 	if (yych <= '`') goto yy39;
671 	if (yych <= 'z') goto yy41;
672 yy39:
673 	++YYCURSOR;
674 #line 371 "ext/standard/url_scanner_ex.re"
675 	{ passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
676 #line 677 "ext/standard/url_scanner_ex.c"
677 yy41:
678 	++YYCURSOR;
679 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
680 	yych = *YYCURSOR;
681 	if (yybm[0+yych] & 128) {
682 		goto yy41;
683 	}
684 #line 370 "ext/standard/url_scanner_ex.re"
685 	{ passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
686 #line 687 "ext/standard/url_scanner_ex.c"
687 }
688 #line 372 "ext/standard/url_scanner_ex.re"
689 
690 
691 state_before_val:
692 	start = YYCURSOR;
693 
694 #line 695 "ext/standard/url_scanner_ex.c"
695 {
696 	YYCTYPE yych;
697 	static const unsigned char yybm[] = {
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 		128,   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 		  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 	};
731 	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
732 	yych = *YYCURSOR;
733 	if (yych == ' ') goto yy48;
734 	if (yych == '=') goto yy49;
735 	++YYCURSOR;
736 yy47:
737 #line 378 "ext/standard/url_scanner_ex.re"
738 	{ --YYCURSOR; goto state_next_arg_begin; }
739 #line 740 "ext/standard/url_scanner_ex.c"
740 yy48:
741 	yych = *(YYMARKER = ++YYCURSOR);
742 	if (yych == ' ') goto yy52;
743 	if (yych != '=') goto yy47;
744 yy49:
745 	++YYCURSOR;
746 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
747 	yych = *YYCURSOR;
748 	if (yybm[0+yych] & 128) {
749 		goto yy49;
750 	}
751 #line 377 "ext/standard/url_scanner_ex.re"
752 	{ passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
753 #line 754 "ext/standard/url_scanner_ex.c"
754 yy52:
755 	++YYCURSOR;
756 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
757 	yych = *YYCURSOR;
758 	if (yych == ' ') goto yy52;
759 	if (yych == '=') goto yy49;
760 	YYCURSOR = YYMARKER;
761 	goto yy47;
762 }
763 #line 379 "ext/standard/url_scanner_ex.re"
764 
765 
766 
767 state_val:
768 	start = YYCURSOR;
769 
770 #line 771 "ext/standard/url_scanner_ex.c"
771 {
772 	YYCTYPE yych;
773 	static const unsigned char yybm[] = {
774 		224, 224, 224, 224, 224, 224, 224, 224,
775 		224, 192, 192, 224, 224, 192, 224, 224,
776 		224, 224, 224, 224, 224, 224, 224, 224,
777 		224, 224, 224, 224, 224, 224, 224, 224,
778 		192, 224, 128, 224, 224, 224, 224,  64,
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,   0, 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 		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 	};
807 	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
808 	yych = *YYCURSOR;
809 	if (yybm[0+yych] & 32) {
810 		goto yy57;
811 	}
812 	if (yych <= ' ') goto yy60;
813 	if (yych <= '"') goto yy62;
814 	if (yych <= '\'') goto yy63;
815 	goto yy60;
816 yy57:
817 	++YYCURSOR;
818 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
819 	yych = *YYCURSOR;
820 	if (yybm[0+yych] & 32) {
821 		goto yy57;
822 	}
823 #line 387 "ext/standard/url_scanner_ex.re"
824 	{ handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
825 #line 826 "ext/standard/url_scanner_ex.c"
826 yy60:
827 	++YYCURSOR;
828 yy61:
829 #line 388 "ext/standard/url_scanner_ex.re"
830 	{ passthru(STD_ARGS); goto state_next_arg_begin; }
831 #line 832 "ext/standard/url_scanner_ex.c"
832 yy62:
833 	yych = *(YYMARKER = ++YYCURSOR);
834 	if (yych == '>') goto yy61;
835 	goto yy65;
836 yy63:
837 	yych = *(YYMARKER = ++YYCURSOR);
838 	if (yych == '>') goto yy61;
839 	goto yy70;
840 yy64:
841 	++YYCURSOR;
842 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
843 	yych = *YYCURSOR;
844 yy65:
845 	if (yybm[0+yych] & 64) {
846 		goto yy64;
847 	}
848 	if (yych <= '"') goto yy67;
849 yy66:
850 	YYCURSOR = YYMARKER;
851 	goto yy61;
852 yy67:
853 	++YYCURSOR;
854 #line 385 "ext/standard/url_scanner_ex.re"
855 	{ handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
856 #line 857 "ext/standard/url_scanner_ex.c"
857 yy69:
858 	++YYCURSOR;
859 	if (YYLIMIT <= YYCURSOR) YYFILL(1);
860 	yych = *YYCURSOR;
861 yy70:
862 	if (yybm[0+yych] & 128) {
863 		goto yy69;
864 	}
865 	if (yych >= '(') goto yy66;
866 	++YYCURSOR;
867 #line 386 "ext/standard/url_scanner_ex.re"
868 	{ handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
869 #line 870 "ext/standard/url_scanner_ex.c"
870 }
871 #line 389 "ext/standard/url_scanner_ex.re"
872 
873 
874 stop:
875 	if (YYLIMIT < start) {
876 		/* XXX: Crash avoidance. Need to work with reporter to figure out what goes wrong */
877 		rest = 0;
878 	} else {
879 		rest = YYLIMIT - start;
880 		scdebug(("stopped in state %d at pos %d (%d:%c) %d\n", STATE, YYCURSOR - ctx->buf.c, *YYCURSOR, *YYCURSOR, rest));
881 	}
882 
883 	if (rest) memmove(ZSTR_VAL(ctx->buf.s), start, rest);
884 	ZSTR_LEN(ctx->buf.s) = rest;
885 }
886 
887 
php_url_scanner_adapt_single_url(const char * url,size_t urllen,const char * name,const char * value,size_t * newlen,int urlencode)888 PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen, int urlencode)
889 {
890 	char *result;
891 	smart_str surl = {0};
892 	smart_str buf = {0};
893 	smart_str url_app = {0};
894 	zend_string *encoded;
895 
896 	smart_str_appendl(&surl, url, urllen);
897 
898 	if (urlencode) {
899 		encoded = php_raw_url_encode(name, strlen(name));
900 		smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
901 		zend_string_free(encoded);
902 	} else {
903 		smart_str_appends(&url_app, name);
904 	}
905 	smart_str_appendc(&url_app, '=');
906 	if (urlencode) {
907 		encoded = php_raw_url_encode(value, strlen(value));
908 		smart_str_appendl(&url_app, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
909 		zend_string_free(encoded);
910 	} else {
911 		smart_str_appends(&url_app, value);
912 	}
913 
914 	append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output);
915 
916 	smart_str_0(&buf);
917 	if (newlen) *newlen = ZSTR_LEN(buf.s);
918 	result = estrndup(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s));
919 
920 	smart_str_free(&url_app);
921 	smart_str_free(&buf);
922 
923 	return result;
924 }
925 
926 
url_adapt_ext(const char * src,size_t srclen,size_t * newlen,zend_bool do_flush)927 static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_bool do_flush)
928 {
929 	url_adapt_state_ex_t *ctx;
930 	char *retval;
931 
932 	ctx = &BG(url_adapt_state_ex);
933 
934 	xx_mainloop(ctx, src, srclen);
935 
936 	if (!ctx->result.s) {
937 		smart_str_appendl(&ctx->result, "", 0);
938 		*newlen = 0;
939 	} else {
940 		*newlen = ZSTR_LEN(ctx->result.s);
941 	}
942 	smart_str_0(&ctx->result);
943 	if (do_flush) {
944 		smart_str_append(&ctx->result, ctx->buf.s);
945 		*newlen += ZSTR_LEN(ctx->buf.s);
946 		smart_str_free(&ctx->buf);
947 		smart_str_free(&ctx->val);
948 	}
949 	retval = estrndup(ZSTR_VAL(ctx->result.s), ZSTR_LEN(ctx->result.s));
950 	smart_str_free(&ctx->result);
951 	return retval;
952 }
953 
php_url_scanner_ex_activate(void)954 static int php_url_scanner_ex_activate(void)
955 {
956 	url_adapt_state_ex_t *ctx;
957 
958 	ctx = &BG(url_adapt_state_ex);
959 
960 	memset(ctx, 0, ((size_t) &((url_adapt_state_ex_t *)0)->tags));
961 
962 	return SUCCESS;
963 }
964 
php_url_scanner_ex_deactivate(void)965 static int php_url_scanner_ex_deactivate(void)
966 {
967 	url_adapt_state_ex_t *ctx;
968 
969 	ctx = &BG(url_adapt_state_ex);
970 
971 	smart_str_free(&ctx->result);
972 	smart_str_free(&ctx->buf);
973 	smart_str_free(&ctx->tag);
974 	smart_str_free(&ctx->arg);
975 
976 	return SUCCESS;
977 }
978 
php_url_scanner_output_handler(char * output,size_t output_len,char ** handled_output,size_t * handled_output_len,int mode)979 static void php_url_scanner_output_handler(char *output, size_t output_len, char **handled_output, size_t *handled_output_len, int mode)
980 {
981 	size_t len;
982 
983 	if (ZSTR_LEN(BG(url_adapt_state_ex).url_app.s) != 0) {
984 		*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));
985 		if (sizeof(uint) < sizeof(size_t)) {
986 			if (len > UINT_MAX)
987 				len = UINT_MAX;
988 		}
989 		*handled_output_len = len;
990 	} else if (ZSTR_LEN(BG(url_adapt_state_ex).url_app.s) == 0) {
991 		url_adapt_state_ex_t *ctx = &BG(url_adapt_state_ex);
992 		if (ctx->buf.s && ZSTR_LEN(ctx->buf.s)) {
993 			smart_str_append(&ctx->result, ctx->buf.s);
994 			smart_str_appendl(&ctx->result, output, output_len);
995 
996 			*handled_output = estrndup(ZSTR_VAL(ctx->result.s), ZSTR_LEN(ctx->result.s));
997 			*handled_output_len = ZSTR_LEN(ctx->buf.s) + output_len;
998 
999 			smart_str_free(&ctx->buf);
1000 			smart_str_free(&ctx->result);
1001 		} else {
1002 			*handled_output = estrndup(output, *handled_output_len = output_len);
1003 		}
1004 	} else {
1005 		*handled_output = NULL;
1006 	}
1007 }
1008 
php_url_scanner_add_var(char * name,size_t name_len,char * value,size_t value_len,int urlencode)1009 PHPAPI int php_url_scanner_add_var(char *name, size_t name_len, char *value, size_t value_len, int urlencode)
1010 {
1011 	smart_str sname = {0};
1012 	smart_str svalue = {0};
1013 	zend_string *encoded;
1014 
1015 	if (!BG(url_adapt_state_ex).active) {
1016 		php_url_scanner_ex_activate();
1017 		php_output_start_internal(ZEND_STRL("URL-Rewriter"), php_url_scanner_output_handler, 0, PHP_OUTPUT_HANDLER_STDFLAGS);
1018 		BG(url_adapt_state_ex).active = 1;
1019 	}
1020 
1021 	if (BG(url_adapt_state_ex).url_app.s && ZSTR_LEN(BG(url_adapt_state_ex).url_app.s) != 0) {
1022 		smart_str_appends(&BG(url_adapt_state_ex).url_app, PG(arg_separator).output);
1023 	}
1024 
1025 	if (urlencode) {
1026 		encoded = php_raw_url_encode(name, name_len);
1027 		smart_str_appendl(&sname, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
1028 		zend_string_free(encoded);
1029 		encoded = php_raw_url_encode(value, value_len);
1030 		smart_str_appendl(&svalue, ZSTR_VAL(encoded), ZSTR_LEN(encoded));
1031 		zend_string_free(encoded);
1032 	} else {
1033 		smart_str_appendl(&sname, name, name_len);
1034 		smart_str_appendl(&svalue, value, value_len);
1035 	}
1036 
1037 	smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &sname);
1038 	smart_str_appendc(&BG(url_adapt_state_ex).url_app, '=');
1039 	smart_str_append_smart_str(&BG(url_adapt_state_ex).url_app, &svalue);
1040 
1041 	smart_str_appends(&BG(url_adapt_state_ex).form_app, "<input type=\"hidden\" name=\"");
1042 	smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &sname);
1043 	smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" value=\"");
1044 	smart_str_append_smart_str(&BG(url_adapt_state_ex).form_app, &svalue);
1045 	smart_str_appends(&BG(url_adapt_state_ex).form_app, "\" />");
1046 
1047 	smart_str_free(&sname);
1048 	smart_str_free(&svalue);
1049 
1050 	return SUCCESS;
1051 }
1052 
php_url_scanner_reset_vars(void)1053 PHPAPI int php_url_scanner_reset_vars(void)
1054 {
1055 	if (BG(url_adapt_state_ex).form_app.s) {
1056 		ZSTR_LEN(BG(url_adapt_state_ex).form_app.s) = 0;
1057 	}
1058 	if (BG(url_adapt_state_ex).url_app.s) {
1059 		ZSTR_LEN(BG(url_adapt_state_ex).url_app.s) = 0;
1060 	}
1061 
1062 	return SUCCESS;
1063 }
1064 
PHP_MINIT_FUNCTION(url_scanner)1065 PHP_MINIT_FUNCTION(url_scanner)
1066 {
1067 	BG(url_adapt_state_ex).tags = NULL;
1068 
1069 	BG(url_adapt_state_ex).form_app.s = BG(url_adapt_state_ex).url_app.s = NULL;
1070 
1071 	REGISTER_INI_ENTRIES();
1072 	return SUCCESS;
1073 }
1074 
PHP_MSHUTDOWN_FUNCTION(url_scanner)1075 PHP_MSHUTDOWN_FUNCTION(url_scanner)
1076 {
1077 	UNREGISTER_INI_ENTRIES();
1078 
1079 	return SUCCESS;
1080 }
1081 
PHP_RINIT_FUNCTION(url_scanner)1082 PHP_RINIT_FUNCTION(url_scanner)
1083 {
1084 	BG(url_adapt_state_ex).active = 0;
1085 
1086 	return SUCCESS;
1087 }
1088 
PHP_RSHUTDOWN_FUNCTION(url_scanner)1089 PHP_RSHUTDOWN_FUNCTION(url_scanner)
1090 {
1091 	if (BG(url_adapt_state_ex).active) {
1092 		php_url_scanner_ex_deactivate();
1093 		BG(url_adapt_state_ex).active = 0;
1094 	}
1095 
1096 	smart_str_free(&BG(url_adapt_state_ex).form_app);
1097 	smart_str_free(&BG(url_adapt_state_ex).url_app);
1098 
1099 	return SUCCESS;
1100 }
1101