From 6c32d271d238a18cfc19d98877cdead1ab38f417 Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Tue, 11 Jul 2017 21:50:38 +0300 Subject: [PATCH] Fixed #74892 - Fixed URL rewriting for urls started with # --- NEWS | 4 +- ext/session/tests/bug74892.phpt | 23 ++++++++ ext/standard/url_scanner_ex.c | 98 +++++++++++++++++---------------- ext/standard/url_scanner_ex.re | 10 +++- 4 files changed, 86 insertions(+), 49 deletions(-) create mode 100644 ext/session/tests/bug74892.phpt diff --git a/NEWS b/NEWS index cb18a64a44..cc31377e17 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 7.1.9 - +- Session: + . Fixed bug #74892 (Url Rewriting (trans_sid) not working on urls that start + with "#"). (Andrew Nester) 03 Aug 2017, PHP 7.1.8 diff --git a/ext/session/tests/bug74892.phpt b/ext/session/tests/bug74892.phpt new file mode 100644 index 0000000000..a4c977828a --- /dev/null +++ b/ext/session/tests/bug74892.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #74892 Url Rewriting (trans_sid) not working on urls that start with # +--FILE-- + +

Click This Anchor Tag!

+

External link with anchor

+

External link with anchor 2

+

Internal link

+===DONE=== +--EXPECT-- +

Click This Anchor Tag!

+

External link with anchor

+

External link with anchor 2

+

Internal link

+===DONE=== diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c index 4eb989bea3..f126dff02b 100644 --- a/ext/standard/url_scanner_ex.c +++ b/ext/standard/url_scanner_ex.c @@ -194,6 +194,13 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st return; } + /* Don't modify URLs of the format "#mark" */ + if (url_parts->fragment && '#' == ZSTR_VAL(url->s)[0]) { + smart_str_append_smart_str(dest, url); + php_url_free(url_parts); + return; + } + /* Check protocol. Only http/https is allowed. */ if (url_parts->scheme && strcasecmp("http", url_parts->scheme) @@ -217,13 +224,12 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st * When URL does not have path and query string add "/?". * i.e. If URL is only "?foo=bar", should not add "/?". */ - if (!url_parts->path && !url_parts->query) { + if (!url_parts->path && !url_parts->query && !url_parts->fragment) { /* URL is http://php.net or like */ smart_str_append_smart_str(dest, url); smart_str_appendc(dest, '/'); smart_str_appendc(dest, '?'); smart_str_append_smart_str(dest, url_app); - /* There should not be fragment. Just return */ php_url_free(url_parts); return; } @@ -513,7 +519,7 @@ state_plain_begin: state_plain: start = YYCURSOR; -#line 517 "ext/standard/url_scanner_ex.c" +#line 523 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -563,22 +569,22 @@ yy2: if (yybm[0+yych] & 128) { goto yy2; } -#line 520 "ext/standard/url_scanner_ex.re" +#line 526 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_plain; } -#line 569 "ext/standard/url_scanner_ex.c" +#line 575 "ext/standard/url_scanner_ex.c" yy5: ++YYCURSOR; -#line 519 "ext/standard/url_scanner_ex.re" +#line 525 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; } -#line 574 "ext/standard/url_scanner_ex.c" +#line 580 "ext/standard/url_scanner_ex.c" } -#line 521 "ext/standard/url_scanner_ex.re" +#line 527 "ext/standard/url_scanner_ex.re" state_tag: start = YYCURSOR; -#line 582 "ext/standard/url_scanner_ex.c" +#line 588 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -621,9 +627,9 @@ state_tag: goto yy11; } ++YYCURSOR; -#line 527 "ext/standard/url_scanner_ex.re" +#line 533 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_plain_begin; } -#line 627 "ext/standard/url_scanner_ex.c" +#line 633 "ext/standard/url_scanner_ex.c" yy11: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -631,11 +637,11 @@ yy11: if (yybm[0+yych] & 128) { goto yy11; } -#line 526 "ext/standard/url_scanner_ex.re" +#line 532 "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 637 "ext/standard/url_scanner_ex.c" +#line 643 "ext/standard/url_scanner_ex.c" } -#line 528 "ext/standard/url_scanner_ex.re" +#line 534 "ext/standard/url_scanner_ex.re" state_next_arg_begin: @@ -644,7 +650,7 @@ state_next_arg_begin: state_next_arg: start = YYCURSOR; -#line 648 "ext/standard/url_scanner_ex.c" +#line 654 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -700,9 +706,9 @@ state_next_arg: yy16: ++YYCURSOR; yy17: -#line 539 "ext/standard/url_scanner_ex.re" +#line 545 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_plain_begin; } -#line 706 "ext/standard/url_scanner_ex.c" +#line 712 "ext/standard/url_scanner_ex.c" yy18: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -710,30 +716,30 @@ yy18: if (yybm[0+yych] & 128) { goto yy18; } -#line 537 "ext/standard/url_scanner_ex.re" +#line 543 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_next_arg; } -#line 716 "ext/standard/url_scanner_ex.c" +#line 722 "ext/standard/url_scanner_ex.c" yy21: yych = *++YYCURSOR; if (yych != '>') goto yy17; yy22: ++YYCURSOR; -#line 536 "ext/standard/url_scanner_ex.re" +#line 542 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; } -#line 724 "ext/standard/url_scanner_ex.c" +#line 730 "ext/standard/url_scanner_ex.c" yy24: ++YYCURSOR; -#line 538 "ext/standard/url_scanner_ex.re" +#line 544 "ext/standard/url_scanner_ex.re" { --YYCURSOR; STATE = STATE_ARG; goto state_arg; } -#line 729 "ext/standard/url_scanner_ex.c" +#line 735 "ext/standard/url_scanner_ex.c" } -#line 540 "ext/standard/url_scanner_ex.re" +#line 546 "ext/standard/url_scanner_ex.re" state_arg: start = YYCURSOR; -#line 737 "ext/standard/url_scanner_ex.c" +#line 743 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -778,9 +784,9 @@ state_arg: if (yych <= 'z') goto yy30; yy28: ++YYCURSOR; -#line 546 "ext/standard/url_scanner_ex.re" +#line 552 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; } -#line 784 "ext/standard/url_scanner_ex.c" +#line 790 "ext/standard/url_scanner_ex.c" yy30: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -788,17 +794,17 @@ yy30: if (yybm[0+yych] & 128) { goto yy30; } -#line 545 "ext/standard/url_scanner_ex.re" +#line 551 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; } -#line 794 "ext/standard/url_scanner_ex.c" +#line 800 "ext/standard/url_scanner_ex.c" } -#line 547 "ext/standard/url_scanner_ex.re" +#line 553 "ext/standard/url_scanner_ex.re" state_before_val: start = YYCURSOR; -#line 802 "ext/standard/url_scanner_ex.c" +#line 808 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -841,9 +847,9 @@ state_before_val: if (yych == '=') goto yy38; ++YYCURSOR; yy36: -#line 553 "ext/standard/url_scanner_ex.re" +#line 559 "ext/standard/url_scanner_ex.re" { --YYCURSOR; goto state_next_arg_begin; } -#line 847 "ext/standard/url_scanner_ex.c" +#line 853 "ext/standard/url_scanner_ex.c" yy37: yych = *(YYMARKER = ++YYCURSOR); if (yych == ' ') goto yy41; @@ -855,9 +861,9 @@ yy38: if (yybm[0+yych] & 128) { goto yy38; } -#line 552 "ext/standard/url_scanner_ex.re" +#line 558 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; } -#line 861 "ext/standard/url_scanner_ex.c" +#line 867 "ext/standard/url_scanner_ex.c" yy41: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -867,14 +873,14 @@ yy41: YYCURSOR = YYMARKER; goto yy36; } -#line 554 "ext/standard/url_scanner_ex.re" +#line 560 "ext/standard/url_scanner_ex.re" state_val: start = YYCURSOR; -#line 878 "ext/standard/url_scanner_ex.c" +#line 884 "ext/standard/url_scanner_ex.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -927,15 +933,15 @@ yy46: if (yybm[0+yych] & 32) { goto yy46; } -#line 562 "ext/standard/url_scanner_ex.re" +#line 568 "ext/standard/url_scanner_ex.re" { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; } -#line 933 "ext/standard/url_scanner_ex.c" +#line 939 "ext/standard/url_scanner_ex.c" yy49: ++YYCURSOR; yy50: -#line 563 "ext/standard/url_scanner_ex.re" +#line 569 "ext/standard/url_scanner_ex.re" { passthru(STD_ARGS); goto state_next_arg_begin; } -#line 939 "ext/standard/url_scanner_ex.c" +#line 945 "ext/standard/url_scanner_ex.c" yy51: yych = *(YYMARKER = ++YYCURSOR); if (yych == '>') goto yy50; @@ -958,9 +964,9 @@ yy55: goto yy50; yy56: ++YYCURSOR; -#line 560 "ext/standard/url_scanner_ex.re" +#line 566 "ext/standard/url_scanner_ex.re" { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; } -#line 964 "ext/standard/url_scanner_ex.c" +#line 970 "ext/standard/url_scanner_ex.c" yy58: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); @@ -971,11 +977,11 @@ yy59: } if (yych >= '(') goto yy55; ++YYCURSOR; -#line 561 "ext/standard/url_scanner_ex.re" +#line 567 "ext/standard/url_scanner_ex.re" { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; } -#line 977 "ext/standard/url_scanner_ex.c" +#line 983 "ext/standard/url_scanner_ex.c" } -#line 564 "ext/standard/url_scanner_ex.re" +#line 570 "ext/standard/url_scanner_ex.re" stop: diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 51a29b5f73..b020b25b6c 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -197,6 +197,13 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st return; } + /* Don't modify URLs of the format "#mark" */ + if (url_parts->fragment && '#' == ZSTR_VAL(url->s)[0]) { + smart_str_append_smart_str(dest, url); + php_url_free(url_parts); + return; + } + /* Check protocol. Only http/https is allowed. */ if (url_parts->scheme && strcasecmp("http", url_parts->scheme) @@ -220,13 +227,12 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st * When URL does not have path and query string add "/?". * i.e. If URL is only "?foo=bar", should not add "/?". */ - if (!url_parts->path && !url_parts->query) { + if (!url_parts->path && !url_parts->query && !url_parts->fragment) { /* URL is http://php.net or like */ smart_str_append_smart_str(dest, url); smart_str_appendc(dest, '/'); smart_str_appendc(dest, '?'); smart_str_append_smart_str(dest, url_app); - /* There should not be fragment. Just return */ php_url_free(url_parts); return; } -- 2.40.0