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 00000000000..ce91b27a003 --- /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-- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+
+
+--EXPECT-- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+
+
diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c index 07ebbe09a21..5db9c6d9358 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" /* +----------------------------------------------------------------------+ @@ -115,11 +115,37 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st const char *bash = NULL; const char *sep = "?"; + /* + * Don't modify "//example.com" full path, unless + * HTTP_HOST matches. + */ + if (ZSTR_VAL(url->s)[0] == '/' && ZSTR_VAL(url->s)[1] == '/') { + zval *tmp = NULL, *http_host = NULL; + size_t target_len, host_len; + if ((!(tmp = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_SERVER")))) + || Z_TYPE_P(tmp) != IS_ARRAY + || !(http_host = zend_hash_str_find(HASH_OF(tmp), ZEND_STRL("HTTP_HOST"))) + || Z_TYPE_P(http_host) != IS_STRING) { + smart_str_append_smart_str(dest, url); + return; + } + /* HTTP_HOST could be "example.com:8888", etc. */ + /* Need to find end of URL in buffer */ + host_len = strcspn(Z_STRVAL_P(http_host), ":"); + target_len = strcspn(ZSTR_VAL(url->s)+2, "/\"'?>\r\n"); + if (host_len + && host_len == target_len + && strncasecmp(Z_STRVAL_P(http_host), ZSTR_VAL(url->s)+2, host_len)) { + smart_str_append_smart_str(dest, url); + return; + } + } + q = (p = ZSTR_VAL(url->s)) + ZSTR_LEN(url->s); scan: -#line 123 "ext/standard/url_scanner_ex.c" +#line 149 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -162,22 +188,22 @@ scan: if (yybm[0+yych] & 128) { goto yy8; } - if (yych <= '9') goto yy6; + if (yych <= '#') goto yy6; if (yych >= ';') goto yy4; ++YYCURSOR; -#line 125 "ext/standard/url_scanner_ex.re" +#line 151 "ext/standard/url_scanner_ex.re" { smart_str_append_smart_str(dest, url); return; } -#line 171 "ext/standard/url_scanner_ex.c" +#line 197 "ext/standard/url_scanner_ex.c" yy4: ++YYCURSOR; -#line 126 "ext/standard/url_scanner_ex.re" +#line 152 "ext/standard/url_scanner_ex.re" { sep = separator; goto scan; } -#line 176 "ext/standard/url_scanner_ex.c" +#line 202 "ext/standard/url_scanner_ex.c" yy6: ++YYCURSOR; -#line 127 "ext/standard/url_scanner_ex.re" +#line 153 "ext/standard/url_scanner_ex.re" { bash = p - 1; goto done; } -#line 181 "ext/standard/url_scanner_ex.c" +#line 207 "ext/standard/url_scanner_ex.c" yy8: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -185,11 +211,11 @@ yy8: if (yybm[0+yych] & 128) { goto yy8; } -#line 128 "ext/standard/url_scanner_ex.re" +#line 154 "ext/standard/url_scanner_ex.re" { goto scan; } -#line 191 "ext/standard/url_scanner_ex.c" +#line 217 "ext/standard/url_scanner_ex.c" } -#line 129 "ext/standard/url_scanner_ex.re" +#line 155 "ext/standard/url_scanner_ex.re" done: @@ -374,7 +400,7 @@ state_plain_begin: state_plain: start = YYCURSOR; -#line 378 "ext/standard/url_scanner_ex.c" +#line 404 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -417,9 +443,9 @@ state_plain: goto yy15; } ++YYCURSOR; -#line 313 "ext/standard/url_scanner_ex.re" +#line 339 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; } -#line 423 "ext/standard/url_scanner_ex.c" +#line 449 "ext/standard/url_scanner_ex.c" yy15: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -427,17 +453,17 @@ yy15: if (yybm[0+yych] & 128) { goto yy15; } -#line 314 "ext/standard/url_scanner_ex.re" +#line 340 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_plain; } -#line 433 "ext/standard/url_scanner_ex.c" +#line 459 "ext/standard/url_scanner_ex.c" } -#line 315 "ext/standard/url_scanner_ex.re" +#line 341 "ext/standard/url_scanner_ex.re" state_tag: start = YYCURSOR; -#line 441 "ext/standard/url_scanner_ex.c" +#line 467 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -488,14 +514,14 @@ yy20: yych = *YYCURSOR; goto yy25; yy21: -#line 320 "ext/standard/url_scanner_ex.re" +#line 346 "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 494 "ext/standard/url_scanner_ex.c" +#line 520 "ext/standard/url_scanner_ex.c" yy22: ++YYCURSOR; -#line 321 "ext/standard/url_scanner_ex.re" +#line 347 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_plain_begin; } -#line 499 "ext/standard/url_scanner_ex.c" +#line 525 "ext/standard/url_scanner_ex.c" yy24: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -506,7 +532,7 @@ yy25: } goto yy21; } -#line 322 "ext/standard/url_scanner_ex.re" +#line 348 "ext/standard/url_scanner_ex.re" state_next_arg_begin: @@ -515,7 +541,7 @@ state_next_arg_begin: state_next_arg: start = YYCURSOR; -#line 519 "ext/standard/url_scanner_ex.c" +#line 545 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -580,28 +606,28 @@ yy28: ++YYCURSOR; if ((yych = *YYCURSOR) == '>') goto yy39; yy29: -#line 333 "ext/standard/url_scanner_ex.re" +#line 359 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_plain_begin; } -#line 586 "ext/standard/url_scanner_ex.c" +#line 612 "ext/standard/url_scanner_ex.c" yy30: ++YYCURSOR; yy31: -#line 330 "ext/standard/url_scanner_ex.re" +#line 356 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; } -#line 592 "ext/standard/url_scanner_ex.c" +#line 618 "ext/standard/url_scanner_ex.c" yy32: ++YYCURSOR; yych = *YYCURSOR; goto yy38; yy33: -#line 331 "ext/standard/url_scanner_ex.re" +#line 357 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_next_arg; } -#line 600 "ext/standard/url_scanner_ex.c" +#line 626 "ext/standard/url_scanner_ex.c" yy34: ++YYCURSOR; -#line 332 "ext/standard/url_scanner_ex.re" +#line 358 "ext/standard/url_scanner_ex.re" { --YYCURSOR; STATE = STATE_ARG; goto state_arg; } -#line 605 "ext/standard/url_scanner_ex.c" +#line 631 "ext/standard/url_scanner_ex.c" yy36: yych = *++YYCURSOR; goto yy29; @@ -619,13 +645,13 @@ yy39: yych = *YYCURSOR; goto yy31; } -#line 334 "ext/standard/url_scanner_ex.re" +#line 360 "ext/standard/url_scanner_ex.re" state_arg: start = YYCURSOR; -#line 629 "ext/standard/url_scanner_ex.c" +#line 655 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -673,14 +699,14 @@ yy42: yych = *YYCURSOR; goto yy47; yy43: -#line 339 "ext/standard/url_scanner_ex.re" +#line 365 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; } -#line 679 "ext/standard/url_scanner_ex.c" +#line 705 "ext/standard/url_scanner_ex.c" yy44: ++YYCURSOR; -#line 340 "ext/standard/url_scanner_ex.re" +#line 366 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; } -#line 684 "ext/standard/url_scanner_ex.c" +#line 710 "ext/standard/url_scanner_ex.c" yy46: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -691,13 +717,13 @@ yy47: } goto yy43; } -#line 341 "ext/standard/url_scanner_ex.re" +#line 367 "ext/standard/url_scanner_ex.re" state_before_val: start = YYCURSOR; -#line 701 "ext/standard/url_scanner_ex.c" +#line 727 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -744,17 +770,17 @@ yy50: if (yych == ' ') goto yy57; if (yych == '=') goto yy55; yy51: -#line 347 "ext/standard/url_scanner_ex.re" +#line 373 "ext/standard/url_scanner_ex.re" { --YYCURSOR; goto state_next_arg_begin; } -#line 750 "ext/standard/url_scanner_ex.c" +#line 776 "ext/standard/url_scanner_ex.c" yy52: ++YYCURSOR; yych = *YYCURSOR; goto yy56; yy53: -#line 346 "ext/standard/url_scanner_ex.re" +#line 372 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; } -#line 758 "ext/standard/url_scanner_ex.c" +#line 784 "ext/standard/url_scanner_ex.c" yy54: yych = *++YYCURSOR; goto yy51; @@ -776,14 +802,14 @@ yy57: YYCURSOR = YYMARKER; goto yy51; } -#line 348 "ext/standard/url_scanner_ex.re" +#line 374 "ext/standard/url_scanner_ex.re" state_val: start = YYCURSOR; -#line 787 "ext/standard/url_scanner_ex.c" +#line 813 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -844,9 +870,9 @@ state_val: yych = *(YYMARKER = ++YYCURSOR); if (yych != '>') goto yy76; yy63: -#line 357 "ext/standard/url_scanner_ex.re" +#line 383 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_next_arg_begin; } -#line 850 "ext/standard/url_scanner_ex.c" +#line 876 "ext/standard/url_scanner_ex.c" yy64: yych = *(YYMARKER = ++YYCURSOR); if (yych == '>') goto yy63; @@ -856,9 +882,9 @@ yy65: yych = *YYCURSOR; goto yy69; yy66: -#line 356 "ext/standard/url_scanner_ex.re" +#line 382 "ext/standard/url_scanner_ex.re" { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; } -#line 862 "ext/standard/url_scanner_ex.c" +#line 888 "ext/standard/url_scanner_ex.c" yy67: yych = *++YYCURSOR; goto yy63; @@ -879,15 +905,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 355 "ext/standard/url_scanner_ex.re" +#line 381 "ext/standard/url_scanner_ex.re" { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; } -#line 891 "ext/standard/url_scanner_ex.c" +#line 917 "ext/standard/url_scanner_ex.c" yy75: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -896,13 +922,13 @@ yy76: if (yybm[0+yych] & 128) { goto yy75; } - if (yych >= '>') goto yy72; + if (yych >= '#') goto yy72; ++YYCURSOR; -#line 354 "ext/standard/url_scanner_ex.re" +#line 380 "ext/standard/url_scanner_ex.re" { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; } -#line 904 "ext/standard/url_scanner_ex.c" +#line 930 "ext/standard/url_scanner_ex.c" } -#line 358 "ext/standard/url_scanner_ex.re" +#line 384 "ext/standard/url_scanner_ex.re" stop: diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 9eb09527502..945f547d56a 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -118,6 +118,32 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st const char *bash = NULL; const char *sep = "?"; + /* + * Don't modify "//example.com" full path, unless + * HTTP_HOST matches. + */ + if (ZSTR_VAL(url->s)[0] == '/' && ZSTR_VAL(url->s)[1] == '/') { + zval *tmp = NULL, *http_host = NULL; + size_t target_len, host_len; + if ((!(tmp = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_SERVER")))) + || Z_TYPE_P(tmp) != IS_ARRAY + || !(http_host = zend_hash_str_find(HASH_OF(tmp), ZEND_STRL("HTTP_HOST"))) + || Z_TYPE_P(http_host) != IS_STRING) { + smart_str_append_smart_str(dest, url); + return; + } + /* HTTP_HOST could be "example.com:8888", etc. */ + /* Need to find end of URL in buffer */ + host_len = strcspn(Z_STRVAL_P(http_host), ":"); + target_len = strcspn(ZSTR_VAL(url->s)+2, "/\"'?>\r\n"); + if (host_len + && host_len == target_len + && strncasecmp(Z_STRVAL_P(http_host), ZSTR_VAL(url->s)+2, host_len)) { + smart_str_append_smart_str(dest, url); + return; + } + } + q = (p = ZSTR_VAL(url->s)) + ZSTR_LEN(url->s); scan: