com php-src: Fix memory errors in url rewriter: ext/standard/ur l_scanner_ex.c ext/standard/url_scanner_ex.re

[email protected] (Nikita Popov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    cf3ef363232af040b9ec63ecd23b603f7acf3751
Author:    Nikita Popov <[email protected]>         Thu, 16 Feb 2017 17:24:07 +0100
Parents:   708973c9bd4a34482d3d6b2921d4b9b1339bddf0
Branches:  PHP-7.0 PHP-7.1 master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=cf3ef363232af040b9ec63ecd23b603f7acf3751

Log:
Fix memory errors in url rewriter

Strings aren't terminated here...

Changed paths:
  M  ext/standard/url_scanner_ex.c
  M  ext/standard/url_scanner_ex.re
diff_cf3ef363232af040b9ec63ecd23b603f7acf3751.txt (text/plain, 17.8 KB)
diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c
index b6663bb..4469bb5 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 a5cf50e..8bc77db 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)) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.