Skip to content

Commit 965308c

Browse files
committed
uri: Remove the uri_parser parameter from php_uri_instantiate_uri()
Similarly to the previous change to `uri_unserialize()`, the `->parser()` must always match the object for the freeing to be safe. Given that we expect to successfully parse URIs, we can eagerly initialize the resulting URI object when using the `::parse()` methods and destruct it again when parsing fails and `null` is returned instead. The destructor has previously been made safe for this case by initializing the `->uri` field to `NULL`. The `base_url_object` must also match the object that is currently being constructed. Verify this using assertions matching the `->ce` and the `->parser`.
1 parent c4d99e0 commit 965308c

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
lines changed

ext/uri/php_uri.c

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -330,16 +330,33 @@ static zend_result pass_errors_by_ref_and_free(zval *errors_zv, zval *errors)
330330
}
331331

332332
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
333-
INTERNAL_FUNCTION_PARAMETERS, const uri_parser_t *uri_parser, const zend_string *uri_str, const zend_object *base_url_object,
333+
INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const zend_object *base_url_object,
334334
bool should_throw, bool should_update_this_object, zval *errors_zv
335335
) {
336+
337+
uri_object_t *uri_object;
338+
if (should_update_this_object) {
339+
uri_object = Z_URI_OBJECT_P(ZEND_THIS);
340+
} else {
341+
if (EX(func)->common.fn_flags & ZEND_ACC_STATIC) {
342+
object_init_ex(return_value, Z_CE_P(ZEND_THIS));
343+
} else {
344+
object_init_ex(return_value, Z_OBJCE_P(ZEND_THIS));
345+
}
346+
uri_object = Z_URI_OBJECT_P(return_value);
347+
}
348+
349+
const uri_parser_t *uri_parser = uri_object->internal.parser;
350+
336351
zval errors;
337352
ZVAL_UNDEF(&errors);
338353

339354
void *base_url = NULL;
340355
if (base_url_object != NULL) {
356+
ZEND_ASSERT(base_url_object->ce == uri_object->std.ce);
341357
uri_internal_t *internal_base_url = uri_internal_from_obj(base_url_object);
342358
URI_ASSERT_INITIALIZATION(internal_base_url);
359+
ZEND_ASSERT(internal_base_url->parser == uri_parser);
343360
base_url = internal_base_url->uri;
344361
}
345362

@@ -352,6 +369,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
352369
if (pass_errors_by_ref_and_free(errors_zv, &errors) == FAILURE) {
353370
RETURN_THROWS();
354371
}
372+
zval_ptr_dtor(return_value);
355373
RETURN_NULL();
356374
}
357375
}
@@ -361,19 +379,6 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
361379
RETURN_THROWS();
362380
}
363381

364-
uri_object_t *uri_object;
365-
if (should_update_this_object) {
366-
uri_object = Z_URI_OBJECT_P(ZEND_THIS);
367-
} else {
368-
if (EX(func)->common.fn_flags & ZEND_ACC_STATIC) {
369-
object_init_ex(return_value, Z_CE_P(ZEND_THIS));
370-
} else {
371-
object_init_ex(return_value, Z_OBJCE_P(ZEND_THIS));
372-
}
373-
uri_object = Z_URI_OBJECT_P(return_value);
374-
}
375-
376-
uri_object->internal.parser = uri_parser;
377382
uri_object->internal.uri = uri;
378383
}
379384

@@ -388,7 +393,7 @@ static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor
388393
Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, uri_rfc3986_uri_ce)
389394
ZEND_PARSE_PARAMETERS_END();
390395

391-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &php_uri_parser_rfc3986, uri_str, base_url_object, is_constructor, is_constructor, NULL);
396+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, base_url_object, is_constructor, is_constructor, NULL);
392397
}
393398

394399
PHP_METHOD(Uri_Rfc3986_Uri, parse)
@@ -475,7 +480,7 @@ static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor)
475480
Z_PARAM_ZVAL(errors)
476481
ZEND_PARSE_PARAMETERS_END();
477482

478-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &php_uri_parser_whatwg, uri_str, base_url_object, is_constructor, is_constructor, errors);
483+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, base_url_object, is_constructor, is_constructor, errors);
479484
}
480485

481486
PHP_METHOD(Uri_WhatWg_Url, parse)
@@ -690,11 +695,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, resolve)
690695
Z_PARAM_PATH_STR(uri_str)
691696
ZEND_PARSE_PARAMETERS_END();
692697

693-
zend_object *this_object = Z_OBJ_P(ZEND_THIS);
694-
uri_internal_t *internal_uri = uri_internal_from_obj(this_object);
695-
URI_ASSERT_INITIALIZATION(internal_uri);
696-
697-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->parser, uri_str, this_object, true, false, NULL);
698+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, Z_OBJ_P(ZEND_THIS), true, false, NULL);
698699
}
699700

700701
PHP_METHOD(Uri_Rfc3986_Uri, __serialize)
@@ -902,11 +903,7 @@ PHP_METHOD(Uri_WhatWg_Url, resolve)
902903
Z_PARAM_ZVAL(errors)
903904
ZEND_PARSE_PARAMETERS_END();
904905

905-
zend_object *this_object = Z_OBJ_P(ZEND_THIS);
906-
uri_internal_t *internal_uri = uri_internal_from_obj(this_object);
907-
URI_ASSERT_INITIALIZATION(internal_uri);
908-
909-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->parser, uri_str, this_object, true, false, errors);
906+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, Z_OBJ_P(ZEND_THIS), true, false, errors);
910907
}
911908

912909
PHP_METHOD(Uri_WhatWg_Url, __serialize)

ext/uri/php_uri.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri *php_uri_parse_to_struct(
205205
ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_struct_free(php_uri *uri);
206206

207207
ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
208-
INTERNAL_FUNCTION_PARAMETERS, const uri_parser_t *uri_parser, const zend_string *uri_str, const zend_object *base_url_object,
208+
INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const zend_object *base_url_object,
209209
bool should_throw, bool should_update_this_object, zval *errors_zv
210210
);
211211

0 commit comments

Comments
 (0)