Browse Source

uri: Throw when trying to modify URI objects after creation (#19768)

This will also fix a memory leak, since the constructor did not free any
pre-existing `->uri`.
pull/19080/merge
Tim Düsterhus 1 month ago
committed by GitHub
parent
commit
d4f5c845ad
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      ext/uri/php_uri.c
  2. 117
      ext/uri/tests/065.phpt

11
ext/uri/php_uri.c

@ -323,6 +323,10 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
uri_object_t *uri_object;
if (should_update_this_object) {
uri_object = Z_URI_OBJECT_P(ZEND_THIS);
if (uri_object->internal.uri != NULL) {
zend_throw_error(NULL, "Cannot modify readonly object of class %s", ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
RETURN_THROWS();
}
} else {
if (EX(func)->common.fn_flags & ZEND_ACC_STATIC) {
object_init_ex(return_value, Z_CE_P(ZEND_THIS));
@ -842,7 +846,12 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS)
}
uri_internal_t *internal_uri = uri_internal_from_obj(object);
internal_uri->parser->free(internal_uri->uri);
if (internal_uri->uri != NULL) {
/* Intentionally throw two exceptions for proper chaining. */
zend_throw_error(NULL, "Cannot modify readonly object of class %s", ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name));
RETURN_THROWS();
}
internal_uri->uri = internal_uri->parser->parse(Z_STRVAL_P(uri_zv), Z_STRLEN_P(uri_zv), NULL, NULL, true);
if (internal_uri->uri == NULL) {
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name));

117
ext/uri/tests/065.phpt

@ -0,0 +1,117 @@
--TEST--
Test that overwriting the URI is not possible
--EXTENSIONS--
uri
--FILE--
<?php
$uri = new Uri\WhatWg\Url('https://example.com');
try {
$uri->__construct('ftp://example.org');
} catch (Throwable $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}
var_dump($uri);
$uri = new Uri\WhatWg\Url('https://example.com');
try {
$uri->__unserialize([['uri' => 'ftp://example.org'], []]);
} catch (Throwable $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}
var_dump($uri);
$uri = new Uri\Rfc3986\Uri('https://example.com');
try {
$uri->__construct('ftp://example.org');
} catch (Throwable $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}
var_dump($uri);
$uri = new Uri\Rfc3986\Uri('https://example.com');
try {
$uri->__unserialize([['uri' => 'ftp://example.org'], []]);
} catch (Throwable $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}
var_dump($uri);
?>
--EXPECTF--
Error: Cannot modify readonly object of class Uri\WhatWg\Url
object(Uri\WhatWg\Url)#%d (8) {
["scheme"]=>
string(5) "https"
["username"]=>
NULL
["password"]=>
NULL
["host"]=>
string(11) "example.com"
["port"]=>
NULL
["path"]=>
string(1) "/"
["query"]=>
NULL
["fragment"]=>
NULL
}
Exception: Invalid serialization data for Uri\WhatWg\Url object
object(Uri\WhatWg\Url)#%d (8) {
["scheme"]=>
string(5) "https"
["username"]=>
NULL
["password"]=>
NULL
["host"]=>
string(11) "example.com"
["port"]=>
NULL
["path"]=>
string(1) "/"
["query"]=>
NULL
["fragment"]=>
NULL
}
Error: Cannot modify readonly object of class Uri\Rfc3986\Uri
object(Uri\Rfc3986\Uri)#%d (8) {
["scheme"]=>
string(5) "https"
["username"]=>
NULL
["password"]=>
NULL
["host"]=>
string(11) "example.com"
["port"]=>
NULL
["path"]=>
string(0) ""
["query"]=>
NULL
["fragment"]=>
NULL
}
Exception: Invalid serialization data for Uri\Rfc3986\Uri object
object(Uri\Rfc3986\Uri)#%d (8) {
["scheme"]=>
string(5) "https"
["username"]=>
NULL
["password"]=>
NULL
["host"]=>
string(11) "example.com"
["port"]=>
NULL
["path"]=>
string(0) ""
["query"]=>
NULL
["fragment"]=>
NULL
}
Loading…
Cancel
Save