Coverage Report

Created: 2026-06-02 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/uri/php_uri_common.c
Line
Count
Source
1
/*
2
   +----------------------------------------------------------------------+
3
   | Copyright © The PHP Group and Contributors.                          |
4
   +----------------------------------------------------------------------+
5
   | This source file is subject to the Modified BSD License that is      |
6
   | bundled with this package in the file LICENSE, and is available      |
7
   | through the World Wide Web at <https://www.php.net/license/>.        |
8
   |                                                                      |
9
   | SPDX-License-Identifier: BSD-3-Clause                                |
10
   +----------------------------------------------------------------------+
11
   | Authors: Máté Kocsis <kocsismate@php.net>                            |
12
   +----------------------------------------------------------------------+
13
*/
14
15
#include "php.h"
16
#include "Zend/zend_interfaces.h"
17
#include "Zend/zend_exceptions.h"
18
#include "php_uri_common.h"
19
20
static zend_string *get_known_string_by_property_name(php_uri_property_name property_name)
21
0
{
22
0
  switch (property_name) {
23
0
    case PHP_URI_PROPERTY_NAME_SCHEME:
24
0
      return ZSTR_KNOWN(ZEND_STR_SCHEME);
25
0
    case PHP_URI_PROPERTY_NAME_USERNAME:
26
0
      return ZSTR_KNOWN(ZEND_STR_USERNAME);
27
0
    case PHP_URI_PROPERTY_NAME_PASSWORD:
28
0
      return ZSTR_KNOWN(ZEND_STR_PASSWORD);
29
0
    case PHP_URI_PROPERTY_NAME_HOST:
30
0
      return ZSTR_KNOWN(ZEND_STR_HOST);
31
0
    case PHP_URI_PROPERTY_NAME_PORT:
32
0
      return ZSTR_KNOWN(ZEND_STR_PORT);
33
0
    case PHP_URI_PROPERTY_NAME_PATH:
34
0
      return ZSTR_KNOWN(ZEND_STR_PATH);
35
0
    case PHP_URI_PROPERTY_NAME_QUERY:
36
0
      return ZSTR_KNOWN(ZEND_STR_QUERY);
37
0
    case PHP_URI_PROPERTY_NAME_FRAGMENT:
38
0
      return ZSTR_KNOWN(ZEND_STR_FRAGMENT);
39
0
    default: ZEND_UNREACHABLE();
40
0
  }
41
0
}
42
43
void php_uri_property_read_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, php_uri_component_read_mode component_read_mode)
44
0
{
45
0
  ZEND_PARSE_PARAMETERS_NONE();
46
47
0
  php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS);
48
0
  ZEND_ASSERT(uri_object->uri != NULL);
49
50
0
  const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(uri_object->parser, property_name);
51
52
0
  if (UNEXPECTED(property_handler->read(uri_object->uri, component_read_mode, return_value) == FAILURE)) {
53
0
    zend_throw_exception_ex(php_uri_ce_error, 0, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name)));
54
0
    RETURN_THROWS();
55
0
  }
56
0
}
57
58
static void php_uri_property_write_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, zval *property_zv)
59
0
{
60
0
  php_uri_object *old_uri_object = Z_URI_OBJECT_P(ZEND_THIS);
61
0
  ZEND_ASSERT(old_uri_object->uri != NULL);
62
63
0
  zend_object *new_object = old_uri_object->std.handlers->clone_obj(&old_uri_object->std);
64
0
  if (new_object == NULL) {
65
0
    RETURN_THROWS();
66
0
  }
67
68
  /* Assign the object early. The engine will take care of destruction in
69
   * case of an exception being thrown. */
70
0
  RETVAL_OBJ(new_object);
71
72
0
  const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(old_uri_object->parser, property_name);
73
74
0
  php_uri_object *new_uri_object = php_uri_object_from_obj(new_object);
75
0
  ZEND_ASSERT(new_uri_object->uri != NULL);
76
0
  if (UNEXPECTED(property_handler->write == NULL)) {
77
0
    zend_readonly_property_modification_error_ex(ZSTR_VAL(old_uri_object->std.ce->name),
78
0
      ZSTR_VAL(get_known_string_by_property_name(property_name)));
79
0
    RETURN_THROWS();
80
0
  }
81
82
0
  zval errors;
83
0
  ZVAL_UNDEF(&errors);
84
0
  if (UNEXPECTED(property_handler->write(new_uri_object->uri, property_zv, &errors) == FAILURE)) {
85
0
    zval_ptr_dtor(&errors);
86
0
    RETURN_THROWS();
87
0
  }
88
89
0
  ZEND_ASSERT(Z_ISUNDEF(errors));
90
0
}
91
92
void php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name)
93
0
{
94
0
  zend_string *value;
95
96
0
  ZEND_PARSE_PARAMETERS_START(1, 1)
97
0
    Z_PARAM_STR(value)
98
0
  ZEND_PARSE_PARAMETERS_END();
99
100
0
  zval zv;
101
0
  ZVAL_STR(&zv, value);
102
103
0
  php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv);
104
0
}
105
106
void php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name)
107
0
{
108
0
  zend_string *value;
109
110
0
  ZEND_PARSE_PARAMETERS_START(1, 1)
111
0
    Z_PARAM_STR_OR_NULL(value)
112
0
  ZEND_PARSE_PARAMETERS_END();
113
114
0
  zval zv;
115
0
  if (value == NULL) {
116
0
    ZVAL_NULL(&zv);
117
0
  } else {
118
0
    ZVAL_STR(&zv, value);
119
0
  }
120
121
0
  php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv);
122
0
}
123
124
void php_uri_property_write_long_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name)
125
0
{
126
0
  zend_long value;
127
0
  bool value_is_null;
128
129
0
  ZEND_PARSE_PARAMETERS_START(1, 1)
130
0
    Z_PARAM_LONG_OR_NULL(value, value_is_null)
131
0
  ZEND_PARSE_PARAMETERS_END();
132
133
0
  zval zv;
134
0
  if (value_is_null) {
135
0
    ZVAL_NULL(&zv);
136
0
  } else {
137
0
    ZVAL_LONG(&zv, value);
138
0
  }
139
140
0
  php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv);
141
0
}