Skip to content

Commit 431174d

Browse files
committed
introduce strict mode
1 parent 56a8baf commit 431174d

File tree

10 files changed

+65
-55
lines changed

10 files changed

+65
-55
lines changed

ext/filter/logical_filters.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
592592
}
593593

594594
/* Use parse_url - if it returns false, we return NULL */
595-
url = php_url_parse_ex(Z_STRVAL_P(value), Z_STRLEN_P(value));
595+
url = php_url_parse_ex(Z_STRVAL_P(value), Z_STRLEN_P(value), false);
596596

597597
if (url == NULL) {
598598
RETURN_VALIDATION_FAILED

ext/soap/php_http.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ int make_http_soap_request(zval *this_ptr,
422422
}
423423

424424
if (location != NULL && location[0] != '\000') {
425-
phpurl = php_url_parse(location);
425+
phpurl = php_url_parse(location, false);
426426
}
427427

428428
tmp = Z_CLIENT_STREAM_CONTEXT_P(this_ptr);
@@ -1096,7 +1096,7 @@ int make_http_soap_request(zval *this_ptr,
10961096
char *loc;
10971097

10981098
if ((loc = get_http_header_value(ZSTR_VAL(http_headers), "Location: ")) != NULL) {
1099-
php_url *new_url = php_url_parse(loc);
1099+
php_url *new_url = php_url_parse(loc, false);
11001100

11011101
if (new_url != NULL) {
11021102
zend_string_release_ex(http_headers, 0);

ext/standard/basic_functions.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3418,7 +3418,7 @@ function uniqid(string $prefix = "", bool $more_entropy = false): string {}
34183418
* @return int|string|array<string, int|string>|null|false
34193419
* @refcount 1
34203420
*/
3421-
function parse_url(string $url, int $component = -1): int|string|array|null|false {}
3421+
function parse_url(string $url, int $component = -1, bool $strict = true): int|string|array|null|false {}
34223422

34233423
/**
34243424
* @compile-time-eval

ext/standard/basic_functions_arginfo.h

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/standard/ftp_fopen_wrapper.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char
133133
char *transport;
134134
int transport_len;
135135

136-
resource = php_url_parse(path);
136+
resource = php_url_parse(path, false);
137137
if (resource == NULL || resource->path == NULL) {
138138
if (resource && presource) {
139139
*presource = resource;
@@ -949,8 +949,8 @@ static int php_stream_ftp_rename(php_stream_wrapper *wrapper, const char *url_fr
949949
int result;
950950
char tmp_line[512];
951951

952-
resource_from = php_url_parse(url_from);
953-
resource_to = php_url_parse(url_to);
952+
resource_from = php_url_parse(url_from, false);
953+
resource_to = php_url_parse(url_to, false);
954954
/* Must be same scheme (ftp/ftp or ftps/ftps), same host, and same port
955955
(or a 21/0 0/21 combination which is also "same")
956956
Also require paths to/from */

ext/standard/http_fopen_wrapper.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
153153
return NULL;
154154
}
155155

156-
resource = php_url_parse(path);
156+
resource = php_url_parse(path, false);
157157
if (resource == NULL) {
158158
return NULL;
159159
}
@@ -888,7 +888,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
888888

889889
php_url_free(resource);
890890
/* check for invalid redirection URLs */
891-
if ((resource = php_url_parse(new_path)) == NULL) {
891+
if ((resource = php_url_parse(new_path, false)) == NULL) {
892892
php_stream_wrapper_log_error(wrapper, options, "Invalid redirect URL! %s", new_path);
893893
goto out;
894894
}

ext/standard/tests/url/parse_url_unterminated.phpt

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,13 @@ include_once(__DIR__ . '/urls.inc');
1414
foreach ($urls as $url) {
1515
echo "\n--> $url: ";
1616
$str = zend_create_unterminated_string($url);
17-
try {
18-
var_dump(parse_url($str));
19-
} catch (ValueError $e) {
20-
echo $e->getMessage() . "\n";
21-
} finally {
22-
zend_terminate_string($str);
23-
}
17+
var_dump(parse_url($str, strict: false));
18+
zend_terminate_string($str);
2419
}
2520

2621
echo "Done";
2722
?>
28-
--EXPECTF--
23+
--EXPECT--
2924
--> 64.246.30.37: array(1) {
3025
["path"]=>
3126
string(12) "64.246.30.37"
@@ -773,7 +768,7 @@ echo "Done";
773768
string(9) "/blah.com"
774769
}
775770

776-
--> x://::abc/?: Invalid port (abc)
771+
--> x://::abc/?: bool(false)
777772

778773
--> http://::?: array(3) {
779774
["scheme"]=>
@@ -802,9 +797,9 @@ echo "Done";
802797
int(6)
803798
}
804799

805-
--> http://?:/: Invalid host (?:/)
800+
--> http://?:/: bool(false)
806801

807-
--> http://@?:/: Invalid host (?:/)
802+
--> http://@?:/: bool(false)
808803

809804
--> file:///:: array(2) {
810805
["scheme"]=>
@@ -895,32 +890,31 @@ echo "Done";
895890
string(1) "/"
896891
}
897892

898-
--> http:///blah.com: Invalid host (%s)
893+
--> http:///blah.com: bool(false)
899894

900-
--> http://:80: Invalid host (%s)
895+
--> http://:80: bool(false)
901896

902-
--> http://user@:80: Invalid host (%s)
897+
--> http://user@:80: bool(false)
903898

904-
--> http://user:pass@:80: Invalid host (%s)
899+
--> http://user:pass@:80: bool(false)
905900

906-
--> http://:: Invalid host (%s)
901+
--> http://:: bool(false)
907902

908-
--> http://@/: Invalid host (%s)
903+
--> http://@/: bool(false)
909904

910-
--> http://@:/: Invalid host (%s)
905+
--> http://@:/: bool(false)
911906

912-
--> http://:/: Invalid host (%s)
907+
--> http://:/: bool(false)
913908

914-
--> http://?: Invalid host (%s)
909+
--> http://?: bool(false)
915910

916-
--> http://#: Invalid host (%s)
911+
--> http://#: bool(false)
917912

918-
--> http://?:: Invalid host (%s)
913+
--> http://?:: bool(false)
919914

920-
--> http://:?: Invalid host (%s)
915+
--> http://:?: bool(false)
921916

922-
--> http://blah.com:123456: Invalid port (%s)
917+
--> http://blah.com:123456: bool(false)
923918

924-
--> http://blah.com:abcdef: Invalid port (%s
925-
)
919+
--> http://blah.com:abcdef: bool(false)
926920
Done

ext/standard/url.c

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ PHPAPI char *php_replace_controlchars(char *str)
7676
return php_replace_controlchars_ex(str, strlen(str));
7777
}
7878

79-
PHPAPI php_url *php_url_parse(char const *str)
79+
PHPAPI php_url *php_url_parse(char const *str, bool strict)
8080
{
81-
return php_url_parse_ex(str, strlen(str));
81+
return php_url_parse_ex(str, strlen(str), strict);
8282
}
8383

8484
static const char *binary_strcspn(const char *s, const char *e, const char *chars) {
@@ -93,15 +93,15 @@ static const char *binary_strcspn(const char *s, const char *e, const char *char
9393
}
9494

9595
/* {{{ php_url_parse */
96-
PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
96+
PHPAPI php_url *php_url_parse_ex(char const *str, size_t length, bool strict)
9797
{
9898
bool has_port;
99-
return php_url_parse_ex2(str, length, &has_port);
99+
return php_url_parse_ex2(str, length, strict, &has_port);
100100
}
101101

102102
/* {{{ php_url_parse_ex2
103103
*/
104-
PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port)
104+
PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool strict, bool *has_port)
105105
{
106106
char port_buf[6];
107107
php_url *ret = ecalloc(1, sizeof(php_url));
@@ -203,12 +203,16 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
203203
s += 2;
204204
}
205205
} else {
206-
zend_value_error("Invalid port (%s)", port_buf);
206+
if (strict) {
207+
zend_value_error("Invalid port (%s)", port_buf);
208+
}
207209
php_url_free(ret);
208210
return NULL;
209211
}
210212
} else if (p == pp && pp == ue) {
211-
zend_value_error("Invalid path (%s)", str);
213+
if (strict) {
214+
zend_value_error("Invalid path (%s)", str);
215+
}
212216
php_url_free(ret);
213217
return NULL;
214218
} else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
@@ -256,7 +260,9 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
256260
if (!ret->port) {
257261
p++;
258262
if (e-p > 5) { /* port cannot be longer then 5 characters */
259-
zend_value_error("Invalid port (%s)", p);
263+
if (strict) {
264+
zend_value_error("Invalid port (%s)", p);
265+
}
260266
php_url_free(ret);
261267
return NULL;
262268
} else if (e - p > 0) {
@@ -269,7 +275,9 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
269275
*has_port = 1;
270276
ret->port = (unsigned short)port;
271277
} else {
272-
zend_value_error("Invalid port (%s)", port_buf);
278+
if (strict) {
279+
zend_value_error("Invalid port (%s)", port_buf);
280+
}
273281
php_url_free(ret);
274282
return NULL;
275283
}
@@ -282,7 +290,9 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port
282290

283291
/* check if we have a valid host, if we don't reject the string as url */
284292
if ((p-s) < 1) {
285-
zend_value_error("Invalid host (%s)", s);
293+
if (strict) {
294+
zend_value_error("Invalid host (%s)", s);
295+
}
286296
php_url_free(ret);
287297
return NULL;
288298
}
@@ -340,18 +350,23 @@ PHP_FUNCTION(parse_url)
340350
php_url *resource;
341351
zend_long key = -1;
342352
zval tmp;
343-
bool has_port;
353+
bool has_port, strict = true;
344354

345-
ZEND_PARSE_PARAMETERS_START(1, 2)
355+
ZEND_PARSE_PARAMETERS_START(1, 3)
346356
Z_PARAM_STRING(str, str_len)
347357
Z_PARAM_OPTIONAL
348358
Z_PARAM_LONG(key)
359+
Z_PARAM_BOOL(strict)
349360
ZEND_PARSE_PARAMETERS_END();
350361

351-
resource = php_url_parse_ex2(str, str_len, &has_port);
362+
resource = php_url_parse_ex2(str, str_len, strict, &has_port);
352363
if (resource == NULL) {
353364
/* @todo Find a method to determine why php_url_parse_ex() failed */
354-
RETURN_FALSE;
365+
if (strict) {
366+
RETURN_THROWS();
367+
} else {
368+
RETURN_FALSE;
369+
}
355370
}
356371

357372
if (key > -1) {

ext/standard/url.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ typedef struct php_url {
2929
} php_url;
3030

3131
PHPAPI void php_url_free(php_url *theurl);
32-
PHPAPI php_url *php_url_parse(char const *str);
33-
PHPAPI php_url *php_url_parse_ex(char const *str, size_t length);
34-
PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port);
32+
PHPAPI php_url *php_url_parse(char const *str, bool strict);
33+
PHPAPI php_url *php_url_parse_ex(char const *str, size_t length, bool strict);
34+
PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool strict, bool *has_port);
3535
PHPAPI size_t php_url_decode(char *str, size_t len); /* return value: length of decoded string */
3636
PHPAPI size_t php_raw_url_decode(char *str, size_t len); /* return value: length of decoded string */
3737
PHPAPI zend_string *php_url_encode(char const *s, size_t len);

ext/standard/url_scanner_ex.re

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ static inline void append_modified_url(smart_str *url, smart_str *dest, smart_st
185185
php_url *url_parts;
186186

187187
smart_str_0(url); /* FIXME: Bug #70480 php_url_parse_ex() crashes by processing chars exceed len */
188-
url_parts = php_url_parse_ex(ZSTR_VAL(url->s), ZSTR_LEN(url->s));
188+
url_parts = php_url_parse_ex(ZSTR_VAL(url->s), ZSTR_LEN(url->s), false);
189189

190190
/* Ignore malformed URLs */
191191
if (!url_parts) {
@@ -380,7 +380,7 @@ static int check_host_whitelist(url_adapt_state_ex_t *ctx)
380380
ZEND_ASSERT(ctx->tag_type == TAG_FORM);
381381

382382
if (ctx->attr_val.s && ZSTR_LEN(ctx->attr_val.s)) {
383-
url_parts = php_url_parse_ex(ZSTR_VAL(ctx->attr_val.s), ZSTR_LEN(ctx->attr_val.s));
383+
url_parts = php_url_parse_ex(ZSTR_VAL(ctx->attr_val.s), ZSTR_LEN(ctx->attr_val.s), false);
384384
} else {
385385
return SUCCESS; /* empty URL is valid */
386386
}

0 commit comments

Comments
 (0)