Last active
August 10, 2016 20:08
-
-
Save yohgaki/4af935d2913fcd6cb25c551eb08a777b to your computer and use it in GitHub Desktop.
URL rewriter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ext/standard/tests/general_functions/url_rewriter.phpt b/ext/standard/tests/general_functions/url_rewriter.phpt | |
new file mode 100644 | |
index 0000000..ce91b27 | |
--- /dev/null | |
+++ b/ext/standard/tests/general_functions/url_rewriter.phpt | |
@@ -0,0 +1,139 @@ | |
+--TEST-- | |
+URL Rewriter tests | |
+--INI-- | |
+url_rewriter.tags="a=href,form=" | |
+session.use_only_cookies=0 | |
+session.use_trans_sid=1 | |
+session.use_strict_mode=0 | |
+--FILE-- | |
+<?php | |
+session_id('id'); | |
+ | |
+$_SERVER['HTTP_HOST'] = 'php.net'; | |
+session_start(); | |
+output_add_rewrite_var('a','b'); | |
+?> | |
+ | |
+<a></a> | |
+<a href=""></a> | |
+<a href="foo"></a> | |
+<a href="?foo"></a> | |
+<a href="/foo"></a> | |
+<a href="foo=bar"></a> | |
+<a href="foo.php#bar"></a> | |
+<a href="../foo.php#bar"></a> | |
+ | |
+<a href="//bad.net/foo"></a> | |
+<a href="//bad.net/?foo"></a> | |
+<a href="//bad.net/foo"></a> | |
+<a href="//bad.net/foo=bar"></a> | |
+<a href="//bad.net/foo.php#bar"></a> | |
+<a href="//bad.net/../foo.php#bar"></a> | |
+ | |
+<a href="//php.net/foo"></a> | |
+<a href="//php.net/?foo"></a> | |
+<a href="//php.net//foo"></a> | |
+<a href="//php.net/foo=bar"></a> | |
+<a href="//php.net/foo.php#bar"></a> | |
+ | |
+<a href="http://bad.net/foo"></a> | |
+<a href="http://bad.net/?foo"></a> | |
+<a href="http://bad.net/foo"></a> | |
+<a href="http://bad.net/foo=bar"></a> | |
+<a href="http://bad.net/foo.php#bar"></a> | |
+<a href="http://bad.net/../foo.php#bar"></a> | |
+ | |
+<a href="http://php.net/foo"></a> | |
+<a href="http://php.net/?foo"></a> | |
+<a href="http://php.net//foo"></a> | |
+<a href="http://php.net/foo=bar"></a> | |
+<a href="http://php.net/foo.php#bar"></a> | |
+<a href="http://php.net/../foo.php#bar"></a> | |
+ | |
+<a href="bad://bad.net/foo"></a> | |
+<a href="bad://bad.net/?foo"></a> | |
+<a href="bad://bad.net/foo"></a> | |
+<a href="bad://bad.net/foo=bar"></a> | |
+<a href="bad://bad.net/foo.php#bar"></a> | |
+<a href="bad://bad.net/../foo.php#bar"></a> | |
+ | |
+<a href="bad://php.net/foo"></a> | |
+<a href="bad://php.net/?foo"></a> | |
+<a href="bad://php.net//foo"></a> | |
+<a href="bad://php.net/foo=bar"></a> | |
+<a href="bad://php.net/foo.php#bar"></a> | |
+<a href="bad://php.net/../foo.php#bar"></a> | |
+ | |
+<form></form> | |
+<form action=""></form> | |
+<form action="foo.php"></form> | |
+<form action="//php.net/foo.php"></form> | |
+<form action="http://php.net/foo.php"></form> | |
+ | |
+<form action="bad://php.net/foo.php"></form> | |
+<form action="//bad.net/foo.php"></form> | |
+<form action="http://php.net/foo.php"></form> | |
+<form action="bad://php.net/foo.php"></form> | |
+<form action="//bad.net/foo.php"></form> | |
+--EXPECT-- | |
+<a></a> | |
+<a href="?PHPSESSID=id&a=b"></a> | |
+<a href="foo?PHPSESSID=id&a=b"></a> | |
+<a href="?foo&PHPSESSID=id&a=b"></a> | |
+<a href="/foo?PHPSESSID=id&a=b"></a> | |
+<a href="foo=bar?PHPSESSID=id&a=b"></a> | |
+<a href="foo.php?PHPSESSID=id&a=b#bar"></a> | |
+<a href="../foo.php?PHPSESSID=id&a=b#bar"></a> | |
+ | |
+<a href="//bad.net/foo"></a> | |
+<a href="//bad.net/?foo"></a> | |
+<a href="//bad.net/foo"></a> | |
+<a href="//bad.net/foo=bar"></a> | |
+<a href="//bad.net/foo.php#bar"></a> | |
+<a href="//bad.net/../foo.php#bar"></a> | |
+ | |
+<a href="//php.net/foo?PHPSESSID=id&a=b"></a> | |
+<a href="//php.net/?foo&PHPSESSID=id&a=b"></a> | |
+<a href="//php.net//foo?PHPSESSID=id&a=b"></a> | |
+<a href="//php.net/foo=bar?PHPSESSID=id&a=b"></a> | |
+<a href="//php.net/foo.php?PHPSESSID=id&a=b#bar"></a> | |
+ | |
+<a href="http://bad.net/foo"></a> | |
+<a href="http://bad.net/?foo"></a> | |
+<a href="http://bad.net/foo"></a> | |
+<a href="http://bad.net/foo=bar"></a> | |
+<a href="http://bad.net/foo.php#bar"></a> | |
+<a href="http://bad.net/../foo.php#bar"></a> | |
+ | |
+<a href="http://php.net/foo"></a> | |
+<a href="http://php.net/?foo"></a> | |
+<a href="http://php.net//foo"></a> | |
+<a href="http://php.net/foo=bar"></a> | |
+<a href="http://php.net/foo.php#bar"></a> | |
+<a href="http://php.net/../foo.php#bar"></a> | |
+ | |
+<a href="bad://bad.net/foo"></a> | |
+<a href="bad://bad.net/?foo"></a> | |
+<a href="bad://bad.net/foo"></a> | |
+<a href="bad://bad.net/foo=bar"></a> | |
+<a href="bad://bad.net/foo.php#bar"></a> | |
+<a href="bad://bad.net/../foo.php#bar"></a> | |
+ | |
+<a href="bad://php.net/foo"></a> | |
+<a href="bad://php.net/?foo"></a> | |
+<a href="bad://php.net//foo"></a> | |
+<a href="bad://php.net/foo=bar"></a> | |
+<a href="bad://php.net/foo.php#bar"></a> | |
+<a href="bad://php.net/../foo.php#bar"></a> | |
+ | |
+<form><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+<form action=""><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+<form action="foo.php"><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+<form action="//php.net/foo.php"><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+<form action="http://php.net/foo.php"><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+ | |
+<form action="bad://php.net/foo.php"><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+<form action="//bad.net/foo.php"><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+<form action="http://php.net/foo.php"><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+<form action="bad://php.net/foo.php"><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
+<form action="//bad.net/foo.php"><input type="hidden" name="PHPSESSID" value="id" /><input type="hidden" name="a" value="b" /></form> | |
diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c | |
index 6b5a2bf..20f82c2 100644 | |
--- a/ext/standard/url_scanner_ex.c | |
+++ b/ext/standard/url_scanner_ex.c | |
@@ -1,4 +1,4 @@ | |
-/* Generated by re2c 0.13.5 */ | |
+/* Generated by re2c 0.14.3 */ | |
#line 1 "ext/standard/url_scanner_ex.re" | |
/* | |
+----------------------------------------------------------------------+ | |
@@ -104,17 +104,43 @@ PHP_INI_END() | |
#define YYLIMIT q | |
#define YYMARKER r | |
-static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator) | |
+static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator TSRMLS_DC) | |
{ | |
register const char *p, *q; | |
const char *bash = NULL; | |
const char *sep = "?"; | |
- | |
+ | |
+ /* | |
+ * Don't modify "//example.com" full path, unless | |
+ * HTTP_HOST matches. | |
+ */ | |
+ if (url->c[0] == '/' && url->c[1] == '/') { | |
+ zval **tmp, **http_host; | |
+ size_t target_len, host_len; | |
+ if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **)&tmp) == FAILURE | |
+ || Z_TYPE_PP(tmp) != IS_ARRAY | |
+ || zend_hash_find(Z_ARRVAL_PP(tmp), "HTTP_HOST", sizeof("HTTP_HOST"), (void **)&http_host) == FAILURE | |
+ || Z_TYPE_PP(http_host) != IS_STRING) { | |
+ smart_str_append(dest, url); | |
+ return; | |
+ } | |
+ /* HTTP_HOST could be "example.com:8888", etc. */ | |
+ /* Need to find end of URL in buffer */ | |
+ host_len = strcspn(Z_STRVAL_PP(http_host), ":"); | |
+ target_len = strcspn(url->c+2, "/\"'?>\r\n"); | |
+ if (host_len | |
+ && host_len == target_len | |
+ && strncasecmp(Z_STRVAL_PP(http_host), url->c+2, host_len)) { | |
+ smart_str_append(dest, url); | |
+ return; | |
+ } | |
+ } | |
+ | |
q = (p = url->c) + url->len; | |
scan: | |
-#line 118 "ext/standard/url_scanner_ex.c" | |
+#line 144 "ext/standard/url_scanner_ex.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -157,22 +183,22 @@ scan: | |
if (yybm[0+yych] & 128) { | |
goto yy8; | |
} | |
- if (yych <= '9') goto yy6; | |
+ if (yych <= '#') goto yy6; | |
if (yych >= ';') goto yy4; | |
++YYCURSOR; | |
-#line 120 "ext/standard/url_scanner_ex.re" | |
+#line 146 "ext/standard/url_scanner_ex.re" | |
{ smart_str_append(dest, url); return; } | |
-#line 166 "ext/standard/url_scanner_ex.c" | |
+#line 192 "ext/standard/url_scanner_ex.c" | |
yy4: | |
++YYCURSOR; | |
-#line 121 "ext/standard/url_scanner_ex.re" | |
+#line 147 "ext/standard/url_scanner_ex.re" | |
{ sep = separator; goto scan; } | |
-#line 171 "ext/standard/url_scanner_ex.c" | |
+#line 197 "ext/standard/url_scanner_ex.c" | |
yy6: | |
++YYCURSOR; | |
-#line 122 "ext/standard/url_scanner_ex.re" | |
+#line 148 "ext/standard/url_scanner_ex.re" | |
{ bash = p - 1; goto done; } | |
-#line 176 "ext/standard/url_scanner_ex.c" | |
+#line 202 "ext/standard/url_scanner_ex.c" | |
yy8: | |
++YYCURSOR; | |
if (YYLIMIT <= YYCURSOR) YYFILL(1); | |
@@ -180,11 +206,11 @@ yy8: | |
if (yybm[0+yych] & 128) { | |
goto yy8; | |
} | |
-#line 123 "ext/standard/url_scanner_ex.re" | |
+#line 149 "ext/standard/url_scanner_ex.re" | |
{ goto scan; } | |
-#line 186 "ext/standard/url_scanner_ex.c" | |
+#line 212 "ext/standard/url_scanner_ex.c" | |
} | |
-#line 124 "ext/standard/url_scanner_ex.re" | |
+#line 150 "ext/standard/url_scanner_ex.re" | |
done: | |
@@ -223,7 +249,7 @@ static inline void tag_arg(url_adapt_state_ex_t *ctx, char quotes, char type TSR | |
if (quotes) | |
smart_str_appendc(&ctx->result, type); | |
if (f) { | |
- append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output); | |
+ append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output TSRMLS_CC); | |
} else { | |
smart_str_append(&ctx->result, &ctx->val); | |
} | |
@@ -364,7 +390,7 @@ state_plain_begin: | |
state_plain: | |
start = YYCURSOR; | |
-#line 368 "ext/standard/url_scanner_ex.c" | |
+#line 394 "ext/standard/url_scanner_ex.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -407,9 +433,9 @@ state_plain: | |
goto yy15; | |
} | |
++YYCURSOR; | |
-#line 303 "ext/standard/url_scanner_ex.re" | |
+#line 329 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; } | |
-#line 413 "ext/standard/url_scanner_ex.c" | |
+#line 439 "ext/standard/url_scanner_ex.c" | |
yy15: | |
++YYCURSOR; | |
if (YYLIMIT <= YYCURSOR) YYFILL(1); | |
@@ -417,17 +443,17 @@ yy15: | |
if (yybm[0+yych] & 128) { | |
goto yy15; | |
} | |
-#line 304 "ext/standard/url_scanner_ex.re" | |
+#line 330 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); goto state_plain; } | |
-#line 423 "ext/standard/url_scanner_ex.c" | |
+#line 449 "ext/standard/url_scanner_ex.c" | |
} | |
-#line 305 "ext/standard/url_scanner_ex.re" | |
+#line 331 "ext/standard/url_scanner_ex.re" | |
state_tag: | |
start = YYCURSOR; | |
-#line 431 "ext/standard/url_scanner_ex.c" | |
+#line 457 "ext/standard/url_scanner_ex.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -478,14 +504,14 @@ yy20: | |
yych = *YYCURSOR; | |
goto yy25; | |
yy21: | |
-#line 310 "ext/standard/url_scanner_ex.re" | |
+#line 336 "ext/standard/url_scanner_ex.re" | |
{ handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; } | |
-#line 484 "ext/standard/url_scanner_ex.c" | |
+#line 510 "ext/standard/url_scanner_ex.c" | |
yy22: | |
++YYCURSOR; | |
-#line 311 "ext/standard/url_scanner_ex.re" | |
+#line 337 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); goto state_plain_begin; } | |
-#line 489 "ext/standard/url_scanner_ex.c" | |
+#line 515 "ext/standard/url_scanner_ex.c" | |
yy24: | |
++YYCURSOR; | |
if (YYLIMIT <= YYCURSOR) YYFILL(1); | |
@@ -496,7 +522,7 @@ yy25: | |
} | |
goto yy21; | |
} | |
-#line 312 "ext/standard/url_scanner_ex.re" | |
+#line 338 "ext/standard/url_scanner_ex.re" | |
state_next_arg_begin: | |
@@ -505,7 +531,7 @@ state_next_arg_begin: | |
state_next_arg: | |
start = YYCURSOR; | |
-#line 509 "ext/standard/url_scanner_ex.c" | |
+#line 535 "ext/standard/url_scanner_ex.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -570,28 +596,28 @@ yy28: | |
++YYCURSOR; | |
if ((yych = *YYCURSOR) == '>') goto yy39; | |
yy29: | |
-#line 323 "ext/standard/url_scanner_ex.re" | |
+#line 349 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); goto state_plain_begin; } | |
-#line 576 "ext/standard/url_scanner_ex.c" | |
+#line 602 "ext/standard/url_scanner_ex.c" | |
yy30: | |
++YYCURSOR; | |
yy31: | |
-#line 320 "ext/standard/url_scanner_ex.re" | |
+#line 346 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; } | |
-#line 582 "ext/standard/url_scanner_ex.c" | |
+#line 608 "ext/standard/url_scanner_ex.c" | |
yy32: | |
++YYCURSOR; | |
yych = *YYCURSOR; | |
goto yy38; | |
yy33: | |
-#line 321 "ext/standard/url_scanner_ex.re" | |
+#line 347 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); goto state_next_arg; } | |
-#line 590 "ext/standard/url_scanner_ex.c" | |
+#line 616 "ext/standard/url_scanner_ex.c" | |
yy34: | |
++YYCURSOR; | |
-#line 322 "ext/standard/url_scanner_ex.re" | |
+#line 348 "ext/standard/url_scanner_ex.re" | |
{ --YYCURSOR; STATE = STATE_ARG; goto state_arg; } | |
-#line 595 "ext/standard/url_scanner_ex.c" | |
+#line 621 "ext/standard/url_scanner_ex.c" | |
yy36: | |
yych = *++YYCURSOR; | |
goto yy29; | |
@@ -609,13 +635,13 @@ yy39: | |
yych = *YYCURSOR; | |
goto yy31; | |
} | |
-#line 324 "ext/standard/url_scanner_ex.re" | |
+#line 350 "ext/standard/url_scanner_ex.re" | |
state_arg: | |
start = YYCURSOR; | |
-#line 619 "ext/standard/url_scanner_ex.c" | |
+#line 645 "ext/standard/url_scanner_ex.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -663,14 +689,14 @@ yy42: | |
yych = *YYCURSOR; | |
goto yy47; | |
yy43: | |
-#line 329 "ext/standard/url_scanner_ex.re" | |
+#line 355 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; } | |
-#line 669 "ext/standard/url_scanner_ex.c" | |
+#line 695 "ext/standard/url_scanner_ex.c" | |
yy44: | |
++YYCURSOR; | |
-#line 330 "ext/standard/url_scanner_ex.re" | |
+#line 356 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; } | |
-#line 674 "ext/standard/url_scanner_ex.c" | |
+#line 700 "ext/standard/url_scanner_ex.c" | |
yy46: | |
++YYCURSOR; | |
if (YYLIMIT <= YYCURSOR) YYFILL(1); | |
@@ -681,13 +707,13 @@ yy47: | |
} | |
goto yy43; | |
} | |
-#line 331 "ext/standard/url_scanner_ex.re" | |
+#line 357 "ext/standard/url_scanner_ex.re" | |
state_before_val: | |
start = YYCURSOR; | |
-#line 691 "ext/standard/url_scanner_ex.c" | |
+#line 717 "ext/standard/url_scanner_ex.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -734,17 +760,17 @@ yy50: | |
if (yych == ' ') goto yy57; | |
if (yych == '=') goto yy55; | |
yy51: | |
-#line 337 "ext/standard/url_scanner_ex.re" | |
+#line 363 "ext/standard/url_scanner_ex.re" | |
{ --YYCURSOR; goto state_next_arg_begin; } | |
-#line 740 "ext/standard/url_scanner_ex.c" | |
+#line 766 "ext/standard/url_scanner_ex.c" | |
yy52: | |
++YYCURSOR; | |
yych = *YYCURSOR; | |
goto yy56; | |
yy53: | |
-#line 336 "ext/standard/url_scanner_ex.re" | |
+#line 362 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; } | |
-#line 748 "ext/standard/url_scanner_ex.c" | |
+#line 774 "ext/standard/url_scanner_ex.c" | |
yy54: | |
yych = *++YYCURSOR; | |
goto yy51; | |
@@ -766,14 +792,14 @@ yy57: | |
YYCURSOR = YYMARKER; | |
goto yy51; | |
} | |
-#line 338 "ext/standard/url_scanner_ex.re" | |
+#line 364 "ext/standard/url_scanner_ex.re" | |
state_val: | |
start = YYCURSOR; | |
-#line 777 "ext/standard/url_scanner_ex.c" | |
+#line 803 "ext/standard/url_scanner_ex.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -834,9 +860,9 @@ state_val: | |
yych = *(YYMARKER = ++YYCURSOR); | |
if (yych != '>') goto yy76; | |
yy63: | |
-#line 347 "ext/standard/url_scanner_ex.re" | |
+#line 373 "ext/standard/url_scanner_ex.re" | |
{ passthru(STD_ARGS); goto state_next_arg_begin; } | |
-#line 840 "ext/standard/url_scanner_ex.c" | |
+#line 866 "ext/standard/url_scanner_ex.c" | |
yy64: | |
yych = *(YYMARKER = ++YYCURSOR); | |
if (yych == '>') goto yy63; | |
@@ -846,9 +872,9 @@ yy65: | |
yych = *YYCURSOR; | |
goto yy69; | |
yy66: | |
-#line 346 "ext/standard/url_scanner_ex.re" | |
+#line 372 "ext/standard/url_scanner_ex.re" | |
{ handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; } | |
-#line 852 "ext/standard/url_scanner_ex.c" | |
+#line 878 "ext/standard/url_scanner_ex.c" | |
yy67: | |
yych = *++YYCURSOR; | |
goto yy63; | |
@@ -869,15 +895,15 @@ yy71: | |
if (yybm[0+yych] & 64) { | |
goto yy70; | |
} | |
- if (yych <= '=') goto yy73; | |
+ if (yych <= '\'') goto yy73; | |
yy72: | |
YYCURSOR = YYMARKER; | |
goto yy63; | |
yy73: | |
++YYCURSOR; | |
-#line 345 "ext/standard/url_scanner_ex.re" | |
+#line 371 "ext/standard/url_scanner_ex.re" | |
{ handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; } | |
-#line 881 "ext/standard/url_scanner_ex.c" | |
+#line 907 "ext/standard/url_scanner_ex.c" | |
yy75: | |
++YYCURSOR; | |
if (YYLIMIT <= YYCURSOR) YYFILL(1); | |
@@ -886,13 +912,13 @@ yy76: | |
if (yybm[0+yych] & 128) { | |
goto yy75; | |
} | |
- if (yych >= '>') goto yy72; | |
+ if (yych >= '#') goto yy72; | |
++YYCURSOR; | |
-#line 344 "ext/standard/url_scanner_ex.re" | |
+#line 370 "ext/standard/url_scanner_ex.re" | |
{ handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; } | |
-#line 894 "ext/standard/url_scanner_ex.c" | |
+#line 920 "ext/standard/url_scanner_ex.c" | |
} | |
-#line 348 "ext/standard/url_scanner_ex.re" | |
+#line 374 "ext/standard/url_scanner_ex.re" | |
stop: | |
@@ -917,7 +943,7 @@ char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const cha | |
smart_str_appendc(&url_app, '='); | |
smart_str_appends(&url_app, value); | |
- append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output); | |
+ append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output TSRMLS_CC); | |
smart_str_0(&buf); | |
if (newlen) *newlen = buf.len; | |
diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re | |
index 851e025..5ee7063 100644 | |
--- a/ext/standard/url_scanner_ex.re | |
+++ b/ext/standard/url_scanner_ex.re | |
@@ -107,12 +107,38 @@ alphadash = ([a-zA-Z] | "-"); | |
#define YYLIMIT q | |
#define YYMARKER r | |
-static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator) | |
+static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator TSRMLS_DC) | |
{ | |
register const char *p, *q; | |
const char *bash = NULL; | |
const char *sep = "?"; | |
- | |
+ | |
+ /* | |
+ * Don't modify "//example.com" full path, unless | |
+ * HTTP_HOST matches. | |
+ */ | |
+ if (url->c[0] == '/' && url->c[1] == '/') { | |
+ zval **tmp, **http_host; | |
+ size_t target_len, host_len; | |
+ if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **)&tmp) == FAILURE | |
+ || Z_TYPE_PP(tmp) != IS_ARRAY | |
+ || zend_hash_find(Z_ARRVAL_PP(tmp), "HTTP_HOST", sizeof("HTTP_HOST"), (void **)&http_host) == FAILURE | |
+ || Z_TYPE_PP(http_host) != IS_STRING) { | |
+ smart_str_append(dest, url); | |
+ return; | |
+ } | |
+ /* HTTP_HOST could be "example.com:8888", etc. */ | |
+ /* Need to find end of URL in buffer */ | |
+ host_len = strcspn(Z_STRVAL_PP(http_host), ":"); | |
+ target_len = strcspn(url->c+2, "/\"'?>\r\n"); | |
+ if (host_len | |
+ && host_len == target_len | |
+ && strncasecmp(Z_STRVAL_PP(http_host), url->c+2, host_len)) { | |
+ smart_str_append(dest, url); | |
+ return; | |
+ } | |
+ } | |
+ | |
q = (p = url->c) + url->len; | |
scan: | |
@@ -159,7 +185,7 @@ static inline void tag_arg(url_adapt_state_ex_t *ctx, char quotes, char type TSR | |
if (quotes) | |
smart_str_appendc(&ctx->result, type); | |
if (f) { | |
- append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output); | |
+ append_modified_url(&ctx->val, &ctx->result, &ctx->url_app, PG(arg_separator).output TSRMLS_CC); | |
} else { | |
smart_str_append(&ctx->result, &ctx->val); | |
} | |
@@ -369,7 +395,7 @@ char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const cha | |
smart_str_appendc(&url_app, '='); | |
smart_str_appends(&url_app, value); | |
- append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output); | |
+ append_modified_url(&surl, &buf, &url_app, PG(arg_separator).output TSRMLS_CC); | |
smart_str_0(&buf); | |
if (newlen) *newlen = buf.len; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment