Skip to content

Commit 239b203

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 ea5239e commit 239b203

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
@@ -332,16 +332,33 @@ static zend_result pass_errors_by_ref_and_free(zval *errors_zv, zval *errors)
332332
}
333333

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

341356
void *base_url = NULL;
342357
if (base_url_object != NULL) {
358+
ZEND_ASSERT(base_url_object->ce == uri_object->std.ce);
343359
uri_internal_t *internal_base_url = uri_internal_from_obj(base_url_object);
344360
URI_ASSERT_INITIALIZATION(internal_base_url);
361+
ZEND_ASSERT(internal_base_url->parser == uri_parser);
345362
base_url = internal_base_url->uri;
346363
}
347364

@@ -354,6 +371,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
354371
if (pass_errors_by_ref_and_free(errors_zv, &errors) == FAILURE) {
355372
RETURN_THROWS();
356373
}
374+
zval_ptr_dtor(return_value);
357375
RETURN_NULL();
358376
}
359377
}
@@ -363,19 +381,6 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
363381
RETURN_THROWS();
364382
}
365383

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

@@ -390,7 +395,7 @@ static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor
390395
Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, uri_rfc3986_uri_ce)
391396
ZEND_PARSE_PARAMETERS_END();
392397

393-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &php_uri_parser_rfc3986, uri_str, base_url_object, is_constructor, is_constructor, NULL);
398+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, base_url_object, is_constructor, is_constructor, NULL);
394399
}
395400

396401
PHP_METHOD(Uri_Rfc3986_Uri, parse)
@@ -477,7 +482,7 @@ static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor)
477482
Z_PARAM_ZVAL(errors)
478483
ZEND_PARSE_PARAMETERS_END();
479484

480-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &php_uri_parser_whatwg, uri_str, base_url_object, is_constructor, is_constructor, errors);
485+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, base_url_object, is_constructor, is_constructor, errors);
481486
}
482487

483488
PHP_METHOD(Uri_WhatWg_Url, parse)
@@ -692,11 +697,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, resolve)
692697
Z_PARAM_PATH_STR(uri_str)
693698
ZEND_PARSE_PARAMETERS_END();
694699

695-
zend_object *this_object = Z_OBJ_P(ZEND_THIS);
696-
uri_internal_t *internal_uri = uri_internal_from_obj(this_object);
697-
URI_ASSERT_INITIALIZATION(internal_uri);
698-
699-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->parser, uri_str, this_object, true, false, NULL);
700+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, Z_OBJ_P(ZEND_THIS), true, false, NULL);
700701
}
701702

702703
PHP_METHOD(Uri_Rfc3986_Uri, __serialize)
@@ -904,11 +905,7 @@ PHP_METHOD(Uri_WhatWg_Url, resolve)
904905
Z_PARAM_ZVAL(errors)
905906
ZEND_PARSE_PARAMETERS_END();
906907

907-
zend_object *this_object = Z_OBJ_P(ZEND_THIS);
908-
uri_internal_t *internal_uri = uri_internal_from_obj(this_object);
909-
URI_ASSERT_INITIALIZATION(internal_uri);
910-
911-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->parser, uri_str, this_object, true, false, errors);
908+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, Z_OBJ_P(ZEND_THIS), true, false, errors);
912909
}
913910

914911
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)