Skip to content

Commit 15388af

Browse files
committed
uri: Fix handling of the errors == NULL && !silent for uri_parser_whatwg
Previously, when `errors` was `NULL`, the `errors` pointer was used to set the `$errors` property when throwing the exception, leading to a crash. Use a local zval to pass the errors to the Exception and copy it into the `errors` input when it is non-`NULL`.
1 parent a09d919 commit 15388af

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

ext/uri/tests/101.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Test the Lexbor-based URI parser
3+
--EXTENSIONS--
4+
uri
5+
zend_test
6+
--FILE--
7+
<?php
8+
9+
try {
10+
var_dump(zend_test_uri_parser('invalid uri', "Uri\\WhatWg\\Url"));
11+
} catch (\Uri\WhatWg\InvalidUrlException $e) {
12+
echo $e->getMessage(), PHP_EOL;
13+
var_dump($e->errors);
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
The specified URI is malformed (MissingSchemeNonRelativeUrl)
19+
array(1) {
20+
[0]=>
21+
object(Uri\WhatWg\UrlValidationError)#%d (3) {
22+
["context"]=>
23+
string(11) "invalid uri"
24+
["type"]=>
25+
enum(Uri\WhatWg\UrlValidationErrorType::MissingSchemeNonRelativeUrl)
26+
["failure"]=>
27+
bool(true)
28+
}
29+
}

ext/uri/uri_parser_whatwg.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,6 @@ static zend_always_inline void zval_long_or_null_to_lexbor_str(zval *value, lexb
6565
*/
6666
static const char *fill_errors(zval *errors)
6767
{
68-
if (errors == NULL) {
69-
return NULL;
70-
}
71-
72-
ZEND_ASSERT(Z_ISUNDEF_P(errors));
73-
7468
array_init(errors);
7569

7670
if (lexbor_parser.log == NULL) {
@@ -224,7 +218,8 @@ static const char *fill_errors(zval *errors)
224218

225219
static void throw_invalid_url_exception_during_write(zval *errors, const char *component)
226220
{
227-
const char *reason = fill_errors(errors);
221+
zval err;
222+
const char *reason = fill_errors(&err);
228223
zend_object *exception = zend_throw_exception_ex(
229224
uri_whatwg_invalid_url_exception_ce,
230225
0,
@@ -234,7 +229,12 @@ static void throw_invalid_url_exception_during_write(zval *errors, const char *c
234229
reason ? reason : "",
235230
reason ? ")" : ""
236231
);
237-
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors);
232+
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), &err);
233+
if (errors) {
234+
zval_ptr_dtor(errors);
235+
ZVAL_COPY(errors, &err);
236+
}
237+
zval_ptr_dtor(&err);
238238
}
239239

240240
static lxb_status_t serialize_to_smart_str_callback(const lxb_char_t *data, size_t length, void *ctx)
@@ -561,11 +561,19 @@ lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, size_t uri_str_le
561561
lxb_url_parser_clean(&lexbor_parser);
562562

563563
lxb_url_t *url = lxb_url_parse(&lexbor_parser, lexbor_base_url, (unsigned char *) uri_str, uri_str_len);
564-
const char *reason = fill_errors(errors);
565564

566-
if (url == NULL && !silent) {
567-
zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? reason : "", reason ? ")" : "");
568-
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors);
565+
if ((url == NULL && !silent) || errors != NULL) {
566+
zval err;
567+
const char *reason = fill_errors(&err);
568+
if (url == NULL && !silent) {
569+
zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? reason : "", reason ? ")" : "");
570+
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), &err);
571+
}
572+
if (errors != NULL) {
573+
zval_ptr_dtor(errors);
574+
ZVAL_COPY(errors, &err);
575+
}
576+
zval_ptr_dtor(&err);
569577
}
570578

571579
return url;

0 commit comments

Comments
 (0)