1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00
Files
archived-php-src/ext/uri/php_uri_common.c
Tim Düsterhus 707f78528c uri: Inline parser and uri into uri_object_t (#19906)
* uri: Inline `uri_internal_from_obj()` and `Z_URI_INTERNAL_P()`

Changes performed with Coccinelle with some minor adjustments in places where
it choked due to macros:

    @@
    expression e;
    @@

    - Z_URI_INTERNAL_P(e)
    + &Z_URI_OBJECT_P(e)->internal

    @@
    expression e;
    @@

    - uri_internal_from_obj(e)
    + &uri_object_from_obj(e)->internal

* uri: Inline definition of `URI_ASSERT_INITIALIZATION()`

While a `NULL` pointer to `zend_object` would result in `->internal` also
sitting at `0`, this is not a particularly useful assertion to have. Instead
just assert that we have a parsed `->uri` available.

Changes made with Coccinelle + some manual adjustments:

    @@
    uri_internal_t *u;
    expression e;
    @@

     u = &Z_URI_OBJECT_P(e)->internal
    ... when != u
    - URI_ASSERT_INITIALIZATION(u);
    + ZEND_ASSERT(u->uri != NULL);

    @@
    uri_internal_t *u;
    expression e;
    @@

     u = &uri_object_from_obj(e)->internal
    ... when != u
    - URI_ASSERT_INITIALIZATION(u);
    + ZEND_ASSERT(u->uri != NULL);

* uri: Inline `parser` and `uri` into `uri_object_t`

After this, `uri_internal_t` will only be used when interacting with the URI
parsers without having a full-blown URI object.

Changes made with Coccinelle and some manual adjustments:

    @@
    identifier u;
    expression e;
    @@

    - uri_internal_t *u = &e->internal;
    + uri_object_t *u = e;

    @@
    uri_object_t *u;
    identifier t;
    @@

    - u->internal.t
    + u->t

* uri: Fix outdated `internal` naming for `uri_object_t`

* uri: Clean up naming of `uri_object_t` variables
2025-09-22 11:46:14 +02:00

144 lines
4.8 KiB
C

/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Máté Kocsis <kocsismate@php.net> |
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "Zend/zend_interfaces.h"
#include "Zend/zend_exceptions.h"
#include "php_uri_common.h"
static zend_string *get_known_string_by_property_name(php_uri_property_name property_name)
{
switch (property_name) {
case PHP_URI_PROPERTY_NAME_SCHEME:
return ZSTR_KNOWN(ZEND_STR_SCHEME);
case PHP_URI_PROPERTY_NAME_USERNAME:
return ZSTR_KNOWN(ZEND_STR_USERNAME);
case PHP_URI_PROPERTY_NAME_PASSWORD:
return ZSTR_KNOWN(ZEND_STR_PASSWORD);
case PHP_URI_PROPERTY_NAME_HOST:
return ZSTR_KNOWN(ZEND_STR_HOST);
case PHP_URI_PROPERTY_NAME_PORT:
return ZSTR_KNOWN(ZEND_STR_PORT);
case PHP_URI_PROPERTY_NAME_PATH:
return ZSTR_KNOWN(ZEND_STR_PATH);
case PHP_URI_PROPERTY_NAME_QUERY:
return ZSTR_KNOWN(ZEND_STR_QUERY);
case PHP_URI_PROPERTY_NAME_FRAGMENT:
return ZSTR_KNOWN(ZEND_STR_FRAGMENT);
EMPTY_SWITCH_DEFAULT_CASE()
}
}
void uri_read_component(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, php_uri_component_read_mode component_read_mode)
{
ZEND_PARSE_PARAMETERS_NONE();
uri_object_t *uri_object = Z_URI_OBJECT_P(ZEND_THIS);
ZEND_ASSERT(uri_object->uri != NULL);
const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(uri_object->parser, property_name);
if (UNEXPECTED(property_handler->read(uri_object->uri, component_read_mode, return_value) == FAILURE)) {
zend_throw_exception_ex(uri_error_ce, 0, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name)));
RETURN_THROWS();
}
}
static void uri_write_component_ex(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, zval *property_zv)
{
uri_object_t *old_uri_object = Z_URI_OBJECT_P(ZEND_THIS);
ZEND_ASSERT(old_uri_object->uri != NULL);
zend_object *new_object = old_uri_object->std.handlers->clone_obj(&old_uri_object->std);
if (new_object == NULL) {
RETURN_THROWS();
}
/* Assign the object early. The engine will take care of destruction in
* case of an exception being thrown. */
RETVAL_OBJ(new_object);
const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(old_uri_object->parser, property_name);
uri_object_t *new_uri_object = uri_object_from_obj(new_object);
ZEND_ASSERT(new_uri_object->uri != NULL);
if (UNEXPECTED(property_handler->write == NULL)) {
zend_readonly_property_modification_error_ex(ZSTR_VAL(old_uri_object->std.ce->name),
ZSTR_VAL(get_known_string_by_property_name(property_name)));
RETURN_THROWS();
}
zval errors;
ZVAL_UNDEF(&errors);
if (UNEXPECTED(property_handler->write(new_uri_object->uri, property_zv, &errors) == FAILURE)) {
zval_ptr_dtor(&errors);
RETURN_THROWS();
}
ZEND_ASSERT(Z_ISUNDEF(errors));
}
void uri_write_component_str(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name)
{
zend_string *value;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH_STR(value)
ZEND_PARSE_PARAMETERS_END();
zval zv;
ZVAL_STR(&zv, value);
uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv);
}
void uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name)
{
zend_string *value;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_PATH_STR_OR_NULL(value)
ZEND_PARSE_PARAMETERS_END();
zval zv;
if (value == NULL) {
ZVAL_NULL(&zv);
} else {
ZVAL_STR(&zv, value);
}
uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv);
}
void uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name)
{
zend_long value;
bool value_is_null;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_LONG_OR_NULL(value, value_is_null)
ZEND_PARSE_PARAMETERS_END();
zval zv;
if (value_is_null) {
ZVAL_NULL(&zv);
} else {
ZVAL_LONG(&zv, value);
}
uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv);
}