Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 57 additions & 49 deletions ext/uri/php_uri.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,16 +332,33 @@ static zend_result pass_errors_by_ref_and_free(zval *errors_zv, zval *errors)
}

ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
INTERNAL_FUNCTION_PARAMETERS, const uri_parser_t *uri_parser, const zend_string *uri_str, const zend_object *base_url_object,
INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const zend_object *base_url_object,
bool should_throw, bool should_update_this_object, zval *errors_zv
) {

uri_object_t *uri_object;
if (should_update_this_object) {
uri_object = Z_URI_OBJECT_P(ZEND_THIS);
} else {
if (EX(func)->common.fn_flags & ZEND_ACC_STATIC) {
object_init_ex(return_value, Z_CE_P(ZEND_THIS));
} else {
object_init_ex(return_value, Z_OBJCE_P(ZEND_THIS));
}
uri_object = Z_URI_OBJECT_P(return_value);
}

const uri_parser_t *uri_parser = uri_object->internal.parser;

zval errors;
ZVAL_UNDEF(&errors);

void *base_url = NULL;
if (base_url_object != NULL) {
ZEND_ASSERT(base_url_object->ce == uri_object->std.ce);
uri_internal_t *internal_base_url = uri_internal_from_obj(base_url_object);
URI_ASSERT_INITIALIZATION(internal_base_url);
ZEND_ASSERT(internal_base_url->parser == uri_parser);
base_url = internal_base_url->uri;
}

Expand All @@ -354,6 +371,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
if (pass_errors_by_ref_and_free(errors_zv, &errors) == FAILURE) {
RETURN_THROWS();
}
zval_ptr_dtor(return_value);
RETURN_NULL();
}
}
Expand All @@ -363,19 +381,6 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
RETURN_THROWS();
}

uri_object_t *uri_object;
if (should_update_this_object) {
uri_object = Z_URI_OBJECT_P(ZEND_THIS);
} else {
if (EX(func)->common.fn_flags & ZEND_ACC_STATIC) {
object_init_ex(return_value, Z_CE_P(ZEND_THIS));
} else {
object_init_ex(return_value, Z_OBJCE_P(ZEND_THIS));
}
uri_object = Z_URI_OBJECT_P(return_value);
}

uri_object->internal.parser = uri_parser;
uri_object->internal.uri = uri;
}

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

php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &php_uri_parser_rfc3986, uri_str, base_url_object, is_constructor, is_constructor, NULL);
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, base_url_object, is_constructor, is_constructor, NULL);
}

PHP_METHOD(Uri_Rfc3986_Uri, parse)
Expand Down Expand Up @@ -477,7 +482,7 @@ static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor)
Z_PARAM_ZVAL(errors)
ZEND_PARSE_PARAMETERS_END();

php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &php_uri_parser_whatwg, uri_str, base_url_object, is_constructor, is_constructor, errors);
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, base_url_object, is_constructor, is_constructor, errors);
}

PHP_METHOD(Uri_WhatWg_Url, parse)
Expand Down Expand Up @@ -692,11 +697,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, resolve)
Z_PARAM_PATH_STR(uri_str)
ZEND_PARSE_PARAMETERS_END();

zend_object *this_object = Z_OBJ_P(ZEND_THIS);
uri_internal_t *internal_uri = uri_internal_from_obj(this_object);
URI_ASSERT_INITIALIZATION(internal_uri);

php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->parser, uri_str, this_object, true, false, NULL);
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, Z_OBJ_P(ZEND_THIS), true, false, NULL);
}

PHP_METHOD(Uri_Rfc3986_Uri, __serialize)
Expand Down Expand Up @@ -729,7 +730,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, __serialize)
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr);
}

static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS, const char *uri_parser_name)
static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS)
{
HashTable *data;

Expand Down Expand Up @@ -765,7 +766,6 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS, const char *uri_parser
}

uri_internal_t *internal_uri = uri_internal_from_obj(object);
internal_uri->parser = uri_parser_by_name(uri_parser_name, strlen(uri_parser_name));
if (internal_uri->uri != NULL) {
internal_uri->parser->free_uri(internal_uri->uri);
}
Expand All @@ -791,7 +791,7 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS, const char *uri_parser

PHP_METHOD(Uri_Rfc3986_Uri, __unserialize)
{
uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PARSER_RFC3986);
uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}

PHP_METHOD(Uri_Rfc3986_Uri, __debugInfo)
Expand Down Expand Up @@ -905,11 +905,7 @@ PHP_METHOD(Uri_WhatWg_Url, resolve)
Z_PARAM_ZVAL(errors)
ZEND_PARSE_PARAMETERS_END();

zend_object *this_object = Z_OBJ_P(ZEND_THIS);
uri_internal_t *internal_uri = uri_internal_from_obj(this_object);
URI_ASSERT_INITIALIZATION(internal_uri);

php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->parser, uri_str, this_object, true, false, errors);
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, Z_OBJ_P(ZEND_THIS), true, false, errors);
}

PHP_METHOD(Uri_WhatWg_Url, __serialize)
Expand Down Expand Up @@ -944,7 +940,7 @@ PHP_METHOD(Uri_WhatWg_Url, __serialize)

PHP_METHOD(Uri_WhatWg_Url, __unserialize)
{
uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PARSER_WHATWG);
uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}

PHP_METHOD(Uri_WhatWg_Url, __debugInfo)
Expand All @@ -956,14 +952,29 @@ PHP_METHOD(Uri_WhatWg_Url, __debugInfo)
RETURN_ARR(uri_get_debug_properties(object));
}

static zend_object *uri_create_object_handler(zend_class_entry *class_type)
static uri_object_t *uri_create_object_handler(zend_class_entry *class_type, const uri_parser_t *parser)
{
uri_object_t *uri_object = zend_object_alloc(sizeof(*uri_object), class_type);

zend_object_std_init(&uri_object->std, class_type);
object_properties_init(&uri_object->std, class_type);

return &uri_object->std;
uri_object->internal = (uri_internal_t){
.parser = parser,
.uri = NULL,
};

return uri_object;
}

static zend_object *uri_create_object_handler_rfc3986(zend_class_entry *ce)
{
return &uri_create_object_handler(ce, &php_uri_parser_rfc3986)->std;
}

static zend_object *uri_create_object_handler_whatwg(zend_class_entry *ce)
{
return &uri_create_object_handler(ce, &php_uri_parser_whatwg)->std;
}

static void uri_free_obj_handler(zend_object *object)
Expand All @@ -986,11 +997,8 @@ zend_object *uri_clone_obj_handler(zend_object *object)

URI_ASSERT_INITIALIZATION(internal_uri);

zend_object *new_object = uri_create_object_handler(object->ce);
ZEND_ASSERT(new_object != NULL);
uri_object_t *new_uri_object = uri_object_from_obj(new_object);

new_uri_object->internal.parser = internal_uri->parser;
uri_object_t *new_uri_object = uri_object_from_obj(object->ce->create_object(object->ce));
ZEND_ASSERT(new_uri_object->internal.parser == internal_uri->parser);

void *uri = internal_uri->parser->clone_uri(internal_uri->uri);
ZEND_ASSERT(uri != NULL);
Expand All @@ -1002,16 +1010,6 @@ zend_object *uri_clone_obj_handler(zend_object *object)
return &new_uri_object->std;
}

ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_implementation_set_object_handlers(zend_class_entry *ce, zend_object_handlers *object_handlers)
{
ce->create_object = uri_create_object_handler;
ce->default_object_handlers = object_handlers;
memcpy(object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
object_handlers->offset = XtOffsetOf(uri_object_t, std);
object_handlers->free_obj = uri_free_obj_handler;
object_handlers->clone_obj = uri_clone_obj_handler;
}

PHPAPI zend_result php_uri_parser_register(const uri_parser_t *uri_parser)
{
zend_string *key = zend_string_init_interned(uri_parser->name, strlen(uri_parser->name), true);
Expand All @@ -1032,10 +1030,20 @@ PHPAPI zend_result php_uri_parser_register(const uri_parser_t *uri_parser)
static PHP_MINIT_FUNCTION(uri)
{
uri_rfc3986_uri_ce = register_class_Uri_Rfc3986_Uri();
php_uri_implementation_set_object_handlers(uri_rfc3986_uri_ce, &uri_rfc3986_uri_object_handlers);
uri_rfc3986_uri_ce->create_object = uri_create_object_handler_rfc3986;
uri_rfc3986_uri_ce->default_object_handlers = &uri_rfc3986_uri_object_handlers;
memcpy(&uri_rfc3986_uri_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
uri_rfc3986_uri_object_handlers.offset = XtOffsetOf(uri_object_t, std);
uri_rfc3986_uri_object_handlers.free_obj = uri_free_obj_handler;
uri_rfc3986_uri_object_handlers.clone_obj = uri_clone_obj_handler;

uri_whatwg_url_ce = register_class_Uri_WhatWg_Url();
php_uri_implementation_set_object_handlers(uri_whatwg_url_ce, &uri_whatwg_uri_object_handlers);
uri_whatwg_url_ce->create_object = uri_create_object_handler_whatwg;
uri_whatwg_url_ce->default_object_handlers = &uri_whatwg_uri_object_handlers;
memcpy(&uri_whatwg_uri_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
uri_whatwg_uri_object_handlers.offset = XtOffsetOf(uri_object_t, std);
uri_whatwg_uri_object_handlers.free_obj = uri_free_obj_handler;
uri_whatwg_uri_object_handlers.clone_obj = uri_clone_obj_handler;

uri_comparison_mode_ce = register_class_Uri_UriComparisonMode();
uri_exception_ce = register_class_Uri_UriException(zend_ce_exception);
Expand Down
4 changes: 1 addition & 3 deletions ext/uri/php_uri.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,8 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri *php_uri_parse_to_struct(
ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_struct_free(php_uri *uri);

ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
INTERNAL_FUNCTION_PARAMETERS, const uri_parser_t *uri_parser, const zend_string *uri_str, const zend_object *base_url_object,
INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const zend_object *base_url_object,
bool should_throw, bool should_update_this_object, zval *errors_zv
);

ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_implementation_set_object_handlers(zend_class_entry *ce, zend_object_handlers *object_handlers);

#endif