summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2017-02-16 17:24:07 +0100
committerNikita Popov <nikita.ppv@gmail.com>2017-02-16 17:24:07 +0100
commitcf3ef363232af040b9ec63ecd23b603f7acf3751 (patch)
treeeb83d8efd56e561a1d756366215ad101c53f0320
parent708973c9bd4a34482d3d6b2921d4b9b1339bddf0 (diff)
downloadphp-git-cf3ef363232af040b9ec63ecd23b603f7acf3751.tar.gz
Fix memory errors in url rewriter
Strings aren't terminated here...
-rw-r--r--ext/standard/url_scanner_ex.c404
-rw-r--r--ext/standard/url_scanner_ex.re9
2 files changed, 179 insertions, 234 deletions
diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c
index b6663bb903..4469bb5e08 100644
--- a/ext/standard/url_scanner_ex.c
+++ b/ext/standard/url_scanner_ex.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.14.3 */
+/* Generated by re2c 0.16 */
#line 1 "ext/standard/url_scanner_ex.re"
/*
+----------------------------------------------------------------------+
@@ -35,6 +35,7 @@
#include "php_ini.h"
#include "php_globals.h"
+#include "php_string.h"
#define STATE_TAG SOME_OTHER_STATE_TAG
#include "basic_functions.h"
#include "url.h"
@@ -100,7 +101,7 @@ PHP_INI_BEGIN()
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()
-#line 107 "ext/standard/url_scanner_ex.re"
+#line 108 "ext/standard/url_scanner_ex.re"
#define YYFILL(n) goto done
@@ -119,7 +120,8 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st
* Don't modify "//example.com" full path, unless
* HTTP_HOST matches.
*/
- if (ZSTR_VAL(url->s)[0] == '/' && ZSTR_VAL(url->s)[1] == '/') {
+ if (ZSTR_LEN(url->s) > 2 && ZSTR_VAL(url->s)[0] == '/' && ZSTR_VAL(url->s)[1] == '/') {
+ const char *end_chars = "/\"'?>\r\n";
zval *tmp = NULL, *http_host = NULL;
size_t target_len, host_len;
if ((!(tmp = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_SERVER"))))
@@ -129,10 +131,13 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st
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");
+ target_len = php_strcspn(
+ ZSTR_VAL(url->s) + 2, (char *) end_chars,
+ ZSTR_VAL(url->s) + ZSTR_LEN(url->s), (char *) end_chars + strlen(end_chars));
if (host_len
&& host_len == target_len
&& strncasecmp(Z_STRVAL_P(http_host), ZSTR_VAL(url->s)+2, host_len)) {
@@ -145,7 +150,7 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st
scan:
-#line 149 "ext/standard/url_scanner_ex.c"
+#line 154 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -182,40 +187,41 @@ scan:
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
};
-
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy8;
+ goto yy2;
}
- if (yych <= '#') goto yy6;
- if (yych >= ';') goto yy4;
- ++YYCURSOR;
-#line 151 "ext/standard/url_scanner_ex.re"
- { smart_str_append_smart_str(dest, url); return; }
-#line 197 "ext/standard/url_scanner_ex.c"
-yy4:
- ++YYCURSOR;
-#line 152 "ext/standard/url_scanner_ex.re"
- { sep = separator; goto scan; }
-#line 202 "ext/standard/url_scanner_ex.c"
-yy6:
- ++YYCURSOR;
-#line 153 "ext/standard/url_scanner_ex.re"
- { bash = p - 1; goto done; }
-#line 207 "ext/standard/url_scanner_ex.c"
-yy8:
+ if (yych <= '#') goto yy5;
+ if (yych <= ':') goto yy7;
+ goto yy9;
+yy2:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy8;
+ goto yy2;
}
-#line 154 "ext/standard/url_scanner_ex.re"
+#line 159 "ext/standard/url_scanner_ex.re"
{ goto scan; }
-#line 217 "ext/standard/url_scanner_ex.c"
+#line 208 "ext/standard/url_scanner_ex.c"
+yy5:
+ ++YYCURSOR;
+#line 158 "ext/standard/url_scanner_ex.re"
+ { bash = p - 1; goto done; }
+#line 213 "ext/standard/url_scanner_ex.c"
+yy7:
+ ++YYCURSOR;
+#line 156 "ext/standard/url_scanner_ex.re"
+ { smart_str_append_smart_str(dest, url); return; }
+#line 218 "ext/standard/url_scanner_ex.c"
+yy9:
+ ++YYCURSOR;
+#line 157 "ext/standard/url_scanner_ex.re"
+ { sep = separator; goto scan; }
+#line 223 "ext/standard/url_scanner_ex.c"
}
-#line 155 "ext/standard/url_scanner_ex.re"
+#line 160 "ext/standard/url_scanner_ex.re"
done:
@@ -400,7 +406,7 @@ state_plain_begin:
state_plain:
start = YYCURSOR;
-#line 404 "ext/standard/url_scanner_ex.c"
+#line 410 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -440,30 +446,32 @@ state_plain:
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy15;
+ goto yy13;
}
- ++YYCURSOR;
-#line 339 "ext/standard/url_scanner_ex.re"
- { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
-#line 449 "ext/standard/url_scanner_ex.c"
-yy15:
+ goto yy16;
+yy13:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy15;
+ goto yy13;
}
-#line 340 "ext/standard/url_scanner_ex.re"
+#line 345 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_plain; }
-#line 459 "ext/standard/url_scanner_ex.c"
+#line 462 "ext/standard/url_scanner_ex.c"
+yy16:
+ ++YYCURSOR;
+#line 344 "ext/standard/url_scanner_ex.re"
+ { passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
+#line 467 "ext/standard/url_scanner_ex.c"
}
-#line 341 "ext/standard/url_scanner_ex.re"
+#line 346 "ext/standard/url_scanner_ex.re"
state_tag:
start = YYCURSOR;
-#line 467 "ext/standard/url_scanner_ex.c"
+#line 475 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -500,39 +508,27 @@ state_tag:
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- if (yych <= '@') {
- if (yych != ':') goto yy22;
- } else {
- if (yych <= 'Z') goto yy20;
- if (yych <= '`') goto yy22;
- if (yych >= '{') goto yy22;
+ if (yybm[0+yych] & 128) {
+ goto yy22;
}
-yy20:
++YYCURSOR;
- yych = *YYCURSOR;
- goto yy25;
-yy21:
-#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 352 "ext/standard/url_scanner_ex.re"
+ { passthru(STD_ARGS); goto state_plain_begin; }
#line 520 "ext/standard/url_scanner_ex.c"
yy22:
++YYCURSOR;
-#line 347 "ext/standard/url_scanner_ex.re"
- { passthru(STD_ARGS); goto state_plain_begin; }
-#line 525 "ext/standard/url_scanner_ex.c"
-yy24:
- ++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy25:
if (yybm[0+yych] & 128) {
- goto yy24;
+ goto yy22;
}
- goto yy21;
+#line 351 "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 530 "ext/standard/url_scanner_ex.c"
}
-#line 348 "ext/standard/url_scanner_ex.re"
+#line 353 "ext/standard/url_scanner_ex.re"
state_next_arg_begin:
@@ -541,7 +537,7 @@ state_next_arg_begin:
state_next_arg:
start = YYCURSOR;
-#line 545 "ext/standard/url_scanner_ex.c"
+#line 541 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -580,78 +576,57 @@ state_next_arg:
};
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
- if (yych <= '.') {
- if (yych <= '\f') {
- if (yych <= 0x08) goto yy36;
- if (yych <= '\v') goto yy32;
- goto yy36;
- } else {
- if (yych <= '\r') goto yy32;
- if (yych == ' ') goto yy32;
- goto yy36;
- }
+ if (yybm[0+yych] & 128) {
+ goto yy29;
+ }
+ if (yych <= '>') {
+ if (yych == '/') goto yy32;
+ if (yych >= '>') goto yy33;
} else {
- if (yych <= '@') {
- if (yych <= '/') goto yy28;
- if (yych == '>') goto yy30;
- goto yy36;
+ if (yych <= 'Z') {
+ if (yych >= 'A') goto yy35;
} else {
- if (yych <= 'Z') goto yy34;
- if (yych <= '`') goto yy36;
- if (yych <= 'z') goto yy34;
- goto yy36;
+ if (yych <= '`') goto yy27;
+ if (yych <= 'z') goto yy35;
}
}
-yy28:
+yy27:
++YYCURSOR;
- if ((yych = *YYCURSOR) == '>') goto yy39;
-yy29:
-#line 359 "ext/standard/url_scanner_ex.re"
+yy28:
+#line 364 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_plain_begin; }
-#line 612 "ext/standard/url_scanner_ex.c"
-yy30:
- ++YYCURSOR;
-yy31:
-#line 356 "ext/standard/url_scanner_ex.re"
- { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
-#line 618 "ext/standard/url_scanner_ex.c"
-yy32:
- ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy38;
-yy33:
-#line 357 "ext/standard/url_scanner_ex.re"
- { passthru(STD_ARGS); goto state_next_arg; }
-#line 626 "ext/standard/url_scanner_ex.c"
-yy34:
- ++YYCURSOR;
-#line 358 "ext/standard/url_scanner_ex.re"
- { --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
-#line 631 "ext/standard/url_scanner_ex.c"
-yy36:
- yych = *++YYCURSOR;
- goto yy29;
-yy37:
+#line 599 "ext/standard/url_scanner_ex.c"
+yy29:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy38:
if (yybm[0+yych] & 128) {
- goto yy37;
+ goto yy29;
}
- goto yy33;
-yy39:
+#line 362 "ext/standard/url_scanner_ex.re"
+ { passthru(STD_ARGS); goto state_next_arg; }
+#line 609 "ext/standard/url_scanner_ex.c"
+yy32:
+ yych = *++YYCURSOR;
+ if (yych != '>') goto yy28;
+yy33:
++YYCURSOR;
- yych = *YYCURSOR;
- goto yy31;
+#line 361 "ext/standard/url_scanner_ex.re"
+ { passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
+#line 617 "ext/standard/url_scanner_ex.c"
+yy35:
+ ++YYCURSOR;
+#line 363 "ext/standard/url_scanner_ex.re"
+ { --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
+#line 622 "ext/standard/url_scanner_ex.c"
}
-#line 360 "ext/standard/url_scanner_ex.re"
+#line 365 "ext/standard/url_scanner_ex.re"
state_arg:
start = YYCURSOR;
-#line 655 "ext/standard/url_scanner_ex.c"
+#line 630 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -688,42 +663,35 @@ state_arg:
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if (yych <= '@') goto yy44;
- if (yych <= 'Z') goto yy42;
- if (yych <= '`') goto yy44;
- if (yych >= '{') goto yy44;
-yy42:
- ++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- goto yy47;
-yy43:
-#line 365 "ext/standard/url_scanner_ex.re"
- { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
-#line 705 "ext/standard/url_scanner_ex.c"
-yy44:
+ if (yych <= '@') goto yy39;
+ if (yych <= 'Z') goto yy41;
+ if (yych <= '`') goto yy39;
+ if (yych <= 'z') goto yy41;
+yy39:
++YYCURSOR;
-#line 366 "ext/standard/url_scanner_ex.re"
+#line 371 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
-#line 710 "ext/standard/url_scanner_ex.c"
-yy46:
+#line 677 "ext/standard/url_scanner_ex.c"
+yy41:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy47:
if (yybm[0+yych] & 128) {
- goto yy46;
+ goto yy41;
}
- goto yy43;
+#line 370 "ext/standard/url_scanner_ex.re"
+ { passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
+#line 687 "ext/standard/url_scanner_ex.c"
}
-#line 367 "ext/standard/url_scanner_ex.re"
+#line 372 "ext/standard/url_scanner_ex.re"
state_before_val:
start = YYCURSOR;
-#line 727 "ext/standard/url_scanner_ex.c"
+#line 695 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -762,54 +730,44 @@ state_before_val:
};
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
- if (yych == ' ') goto yy50;
- if (yych == '=') goto yy52;
- goto yy54;
-yy50:
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ' ') goto yy57;
- if (yych == '=') goto yy55;
-yy51:
-#line 373 "ext/standard/url_scanner_ex.re"
- { --YYCURSOR; goto state_next_arg_begin; }
-#line 776 "ext/standard/url_scanner_ex.c"
-yy52:
+ if (yych == ' ') goto yy48;
+ if (yych == '=') goto yy49;
++YYCURSOR;
- yych = *YYCURSOR;
- goto yy56;
-yy53:
-#line 372 "ext/standard/url_scanner_ex.re"
- { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
-#line 784 "ext/standard/url_scanner_ex.c"
-yy54:
- yych = *++YYCURSOR;
- goto yy51;
-yy55:
+yy47:
+#line 378 "ext/standard/url_scanner_ex.re"
+ { --YYCURSOR; goto state_next_arg_begin; }
+#line 740 "ext/standard/url_scanner_ex.c"
+yy48:
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == ' ') goto yy52;
+ if (yych != '=') goto yy47;
+yy49:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy56:
if (yybm[0+yych] & 128) {
- goto yy55;
+ goto yy49;
}
- goto yy53;
-yy57:
+#line 377 "ext/standard/url_scanner_ex.re"
+ { passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
+#line 754 "ext/standard/url_scanner_ex.c"
+yy52:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- if (yych == ' ') goto yy57;
- if (yych == '=') goto yy55;
+ if (yych == ' ') goto yy52;
+ if (yych == '=') goto yy49;
YYCURSOR = YYMARKER;
- goto yy51;
+ goto yy47;
}
-#line 374 "ext/standard/url_scanner_ex.re"
+#line 379 "ext/standard/url_scanner_ex.re"
state_val:
start = YYCURSOR;
-#line 813 "ext/standard/url_scanner_ex.c"
+#line 771 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -817,7 +775,7 @@ state_val:
224, 192, 192, 224, 224, 192, 224, 224,
224, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 224, 224, 224, 224, 224,
- 192, 224, 64, 224, 224, 224, 224, 128,
+ 192, 224, 128, 224, 224, 224, 224, 64,
224, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 224, 224, 224, 224, 224,
224, 224, 224, 224, 224, 224, 0, 224,
@@ -848,87 +806,69 @@ state_val:
};
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
- if (yych <= ' ') {
- if (yych <= '\f') {
- if (yych <= 0x08) goto yy65;
- if (yych <= '\n') goto yy67;
- goto yy65;
- } else {
- if (yych <= '\r') goto yy67;
- if (yych <= 0x1F) goto yy65;
- goto yy67;
- }
- } else {
- if (yych <= '&') {
- if (yych != '"') goto yy65;
- } else {
- if (yych <= '\'') goto yy64;
- if (yych == '>') goto yy67;
- goto yy65;
- }
+ if (yybm[0+yych] & 32) {
+ goto yy57;
}
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych != '>') goto yy76;
-yy63:
-#line 383 "ext/standard/url_scanner_ex.re"
- { passthru(STD_ARGS); goto state_next_arg_begin; }
-#line 876 "ext/standard/url_scanner_ex.c"
-yy64:
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == '>') goto yy63;
- goto yy71;
-yy65:
- ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy69;
-yy66:
-#line 382 "ext/standard/url_scanner_ex.re"
- { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
-#line 888 "ext/standard/url_scanner_ex.c"
-yy67:
- yych = *++YYCURSOR;
- goto yy63;
-yy68:
+ if (yych <= ' ') goto yy60;
+ if (yych <= '"') goto yy62;
+ if (yych <= '\'') goto yy63;
+ goto yy60;
+yy57:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy69:
if (yybm[0+yych] & 32) {
- goto yy68;
+ goto yy57;
}
- goto yy66;
-yy70:
+#line 387 "ext/standard/url_scanner_ex.re"
+ { handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
+#line 826 "ext/standard/url_scanner_ex.c"
+yy60:
+ ++YYCURSOR;
+yy61:
+#line 388 "ext/standard/url_scanner_ex.re"
+ { passthru(STD_ARGS); goto state_next_arg_begin; }
+#line 832 "ext/standard/url_scanner_ex.c"
+yy62:
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == '>') goto yy61;
+ goto yy65;
+yy63:
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == '>') goto yy61;
+ goto yy70;
+yy64:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy71:
+yy65:
if (yybm[0+yych] & 64) {
- goto yy70;
+ goto yy64;
}
- if (yych <= '\'') goto yy73;
-yy72:
+ if (yych <= '"') goto yy67;
+yy66:
YYCURSOR = YYMARKER;
- goto yy63;
-yy73:
+ goto yy61;
+yy67:
++YYCURSOR;
-#line 381 "ext/standard/url_scanner_ex.re"
- { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
-#line 917 "ext/standard/url_scanner_ex.c"
-yy75:
+#line 385 "ext/standard/url_scanner_ex.re"
+ { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
+#line 857 "ext/standard/url_scanner_ex.c"
+yy69:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy76:
+yy70:
if (yybm[0+yych] & 128) {
- goto yy75;
+ goto yy69;
}
- if (yych >= '#') goto yy72;
+ if (yych >= '(') goto yy66;
++YYCURSOR;
-#line 380 "ext/standard/url_scanner_ex.re"
- { handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
-#line 930 "ext/standard/url_scanner_ex.c"
+#line 386 "ext/standard/url_scanner_ex.re"
+ { handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
+#line 870 "ext/standard/url_scanner_ex.c"
}
-#line 384 "ext/standard/url_scanner_ex.re"
+#line 389 "ext/standard/url_scanner_ex.re"
stop:
diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re
index a5cf50eac3..8bc77db4be 100644
--- a/ext/standard/url_scanner_ex.re
+++ b/ext/standard/url_scanner_ex.re
@@ -33,6 +33,7 @@
#include "php_ini.h"
#include "php_globals.h"
+#include "php_string.h"
#define STATE_TAG SOME_OTHER_STATE_TAG
#include "basic_functions.h"
#include "url.h"
@@ -122,7 +123,8 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st
* Don't modify "//example.com" full path, unless
* HTTP_HOST matches.
*/
- if (ZSTR_VAL(url->s)[0] == '/' && ZSTR_VAL(url->s)[1] == '/') {
+ if (ZSTR_LEN(url->s) > 2 && ZSTR_VAL(url->s)[0] == '/' && ZSTR_VAL(url->s)[1] == '/') {
+ const char *end_chars = "/\"'?>\r\n";
zval *tmp = NULL, *http_host = NULL;
size_t target_len, host_len;
if ((!(tmp = zend_hash_str_find(&EG(symbol_table), ZEND_STRL("_SERVER"))))
@@ -132,10 +134,13 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st
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");
+ target_len = php_strcspn(
+ ZSTR_VAL(url->s) + 2, (char *) end_chars,
+ ZSTR_VAL(url->s) + ZSTR_LEN(url->s), (char *) end_chars + strlen(end_chars));
if (host_len
&& host_len == target_len
&& strncasecmp(Z_STRVAL_P(http_host), ZSTR_VAL(url->s)+2, host_len)) {