Skip to content

Commit 78ef6cb

Browse files
committed
uri: Do not create new UrlValidationErrorType objects
`zend_enum_new()` is not intended to be used “at runtime”, since it will create a new object, breaking the singleton property. Instead `zend_enum_get_case_cstr()` must be used.
1 parent b8b0497 commit 78ef6cb

File tree

3 files changed

+59
-39
lines changed

3 files changed

+59
-39
lines changed

‎NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.5.0alpha2
44

5+
- URI:
6+
. Return the singleton UrlValidationErrorType instances from Uri\WhatWg\Url
7+
instead of creating new objects that are different from the singleton.
8+
(timwolla)
59

610
03 Jul 2025, PHP 8.5.0alpha1
711

‎ext/uri/php_lexbor.c

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static void lexbor_cleanup_parser(void)
7373
* When errors is NULL, the caller is not interested in the additional error information,
7474
* so the function does nothing.
7575
*/
76-
static zend_string *fill_errors(zval *errors)
76+
static const char *fill_errors(zval *errors)
7777
{
7878
if (errors == NULL) {
7979
return NULL;
@@ -87,140 +87,138 @@ static zend_string *fill_errors(zval *errors)
8787
return NULL;
8888
}
8989

90-
zend_string *result = NULL;
90+
const char *result = NULL;
9191
lexbor_plog_entry_t *lxb_error;
9292
while ((lxb_error = lexbor_array_obj_pop(&lexbor_parser.log->list)) != NULL) {
9393
zval error;
9494
object_init_ex(&error, uri_whatwg_url_validation_error_ce);
9595
zend_update_property_string(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("context"), (const char *) lxb_error->data);
9696

97-
zend_string *error_str;
97+
const char *error_str;
9898
zval failure;
9999
switch (lxb_error->id) {
100100
case LXB_URL_ERROR_TYPE_DOMAIN_TO_ASCII:
101-
error_str = ZSTR_INIT_LITERAL("DomainToAscii", false);
101+
error_str = "DomainToAscii";
102102
ZVAL_TRUE(&failure);
103103
break;
104104
case LXB_URL_ERROR_TYPE_DOMAIN_TO_UNICODE:
105-
error_str = ZSTR_INIT_LITERAL("DomainToUnicode", false);
105+
error_str = "DomainToUnicode";
106106
ZVAL_FALSE(&failure);
107107
break;
108108
case LXB_URL_ERROR_TYPE_DOMAIN_INVALID_CODE_POINT:
109-
error_str = ZSTR_INIT_LITERAL("DomainInvalidCodePoint", false);
109+
error_str = "DomainInvalidCodePoint";
110110
ZVAL_TRUE(&failure);
111111
break;
112112
case LXB_URL_ERROR_TYPE_HOST_INVALID_CODE_POINT:
113-
error_str = ZSTR_INIT_LITERAL("HostInvalidCodePoint", false);
113+
error_str = "HostInvalidCodePoint";
114114
ZVAL_TRUE(&failure);
115115
break;
116116
case LXB_URL_ERROR_TYPE_IPV4_EMPTY_PART:
117-
error_str = ZSTR_INIT_LITERAL("Ipv4EmptyPart", false);
117+
error_str = "Ipv4EmptyPart";
118118
ZVAL_FALSE(&failure);
119119
break;
120120
case LXB_URL_ERROR_TYPE_IPV4_TOO_MANY_PARTS:
121-
error_str = ZSTR_INIT_LITERAL("Ipv4TooManyParts", false);
121+
error_str = "Ipv4TooManyParts";
122122
ZVAL_TRUE(&failure);
123123
break;
124124
case LXB_URL_ERROR_TYPE_IPV4_NON_NUMERIC_PART:
125-
error_str = ZSTR_INIT_LITERAL("Ipv4NonNumericPart", false);
125+
error_str = "Ipv4NonNumericPart";
126126
ZVAL_TRUE(&failure);
127127
break;
128128
case LXB_URL_ERROR_TYPE_IPV4_NON_DECIMAL_PART:
129-
error_str = ZSTR_INIT_LITERAL("Ipv4NonDecimalPart", false);
129+
error_str = "Ipv4NonDecimalPart";
130130
ZVAL_FALSE(&failure);
131131
break;
132132
case LXB_URL_ERROR_TYPE_IPV4_OUT_OF_RANGE_PART:
133-
error_str = ZSTR_INIT_LITERAL("Ipv4OutOfRangePart", false);
133+
error_str = "Ipv4OutOfRangePart";
134134
ZVAL_TRUE(&failure);
135135
break;
136136
case LXB_URL_ERROR_TYPE_IPV6_UNCLOSED:
137-
error_str = ZSTR_INIT_LITERAL("Ipv6Unclosed", false);
137+
error_str = "Ipv6Unclosed";
138138
ZVAL_TRUE(&failure);
139139
break;
140140
case LXB_URL_ERROR_TYPE_IPV6_INVALID_COMPRESSION:
141-
error_str = ZSTR_INIT_LITERAL("Ipv6InvalidCompression", false);
141+
error_str = "Ipv6InvalidCompression";
142142
ZVAL_TRUE(&failure);
143143
break;
144144
case LXB_URL_ERROR_TYPE_IPV6_TOO_MANY_PIECES:
145-
error_str = ZSTR_INIT_LITERAL("Ipv6TooManyPieces", false);
145+
error_str = "Ipv6TooManyPieces";
146146
ZVAL_TRUE(&failure);
147147
break;
148148
case LXB_URL_ERROR_TYPE_IPV6_MULTIPLE_COMPRESSION:
149-
error_str = ZSTR_INIT_LITERAL("Ipv6MultipleCompression", false);
149+
error_str = "Ipv6MultipleCompression";
150150
ZVAL_TRUE(&failure);
151151
break;
152152
case LXB_URL_ERROR_TYPE_IPV6_INVALID_CODE_POINT:
153-
error_str = ZSTR_INIT_LITERAL("Ipv6InvalidCodePoint", false);
153+
error_str = "Ipv6InvalidCodePoint";
154154
ZVAL_TRUE(&failure);
155155
break;
156156
case LXB_URL_ERROR_TYPE_IPV6_TOO_FEW_PIECES:
157-
error_str = ZSTR_INIT_LITERAL("Ipv6TooFewPieces", false);
157+
error_str = "Ipv6TooFewPieces";
158158
ZVAL_TRUE(&failure);
159159
break;
160160
case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_TOO_MANY_PIECES:
161-
error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6TooManyPieces", false);
161+
error_str = "Ipv4InIpv6TooManyPieces";
162162
ZVAL_TRUE(&failure);
163163
break;
164164
case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_INVALID_CODE_POINT:
165-
error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6InvalidCodePoint", false);
165+
error_str = "Ipv4InIpv6InvalidCodePoint";
166166
ZVAL_TRUE(&failure);
167167
break;
168168
case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_OUT_OF_RANGE_PART:
169-
error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6OutOfRangePart", false);
169+
error_str = "Ipv4InIpv6OutOfRangePart";
170170
ZVAL_TRUE(&failure);
171171
break;
172172
case LXB_URL_ERROR_TYPE_IPV4_IN_IPV6_TOO_FEW_PARTS:
173-
error_str = ZSTR_INIT_LITERAL("Ipv4InIpv6TooFewParts", false);
173+
error_str = "Ipv4InIpv6TooFewParts";
174174
ZVAL_TRUE(&failure);
175175
break;
176176
case LXB_URL_ERROR_TYPE_INVALID_URL_UNIT:
177-
error_str = ZSTR_INIT_LITERAL("InvalidUrlUnit", false);
177+
error_str = "InvalidUrlUnit";
178178
ZVAL_FALSE(&failure);
179179
break;
180180
case LXB_URL_ERROR_TYPE_SPECIAL_SCHEME_MISSING_FOLLOWING_SOLIDUS:
181-
error_str = ZSTR_INIT_LITERAL("SpecialSchemeMissingFollowingSolidus", false);
181+
error_str = "SpecialSchemeMissingFollowingSolidus";
182182
ZVAL_FALSE(&failure);
183183
break;
184184
case LXB_URL_ERROR_TYPE_MISSING_SCHEME_NON_RELATIVE_URL:
185-
error_str = ZSTR_INIT_LITERAL("MissingSchemeNonRelativeUrl", false);
185+
error_str = "MissingSchemeNonRelativeUrl";
186186
ZVAL_TRUE(&failure);
187187
break;
188188
case LXB_URL_ERROR_TYPE_INVALID_REVERSE_SOLIDUS:
189-
error_str = ZSTR_INIT_LITERAL("InvalidReverseSoldius", false);
189+
error_str = "InvalidReverseSoldius";
190190
ZVAL_FALSE(&failure);
191191
break;
192192
case LXB_URL_ERROR_TYPE_INVALID_CREDENTIALS:
193-
error_str = ZSTR_INIT_LITERAL("InvalidCredentials", false);
193+
error_str = "InvalidCredentials";
194194
ZVAL_FALSE(&failure);
195195
break;
196196
case LXB_URL_ERROR_TYPE_HOST_MISSING:
197-
error_str = ZSTR_INIT_LITERAL("HostMissing", false);
197+
error_str = "HostMissing";
198198
ZVAL_TRUE(&failure);
199199
break;
200200
case LXB_URL_ERROR_TYPE_PORT_OUT_OF_RANGE:
201-
error_str = ZSTR_INIT_LITERAL("PortOutOfRange", false);
201+
error_str = "PortOutOfRange";
202202
ZVAL_TRUE(&failure);
203203
break;
204204
case LXB_URL_ERROR_TYPE_PORT_INVALID:
205-
error_str = ZSTR_INIT_LITERAL("PortInvalid", false);
205+
error_str = "PortInvalid";
206206
ZVAL_TRUE(&failure);
207207
break;
208208
case LXB_URL_ERROR_TYPE_FILE_INVALID_WINDOWS_DRIVE_LETTER:
209-
error_str = ZSTR_INIT_LITERAL("FileInvalidWindowsDriveLetter", false);
209+
error_str = "FileInvalidWindowsDriveLetter";
210210
ZVAL_FALSE(&failure);
211211
break;
212212
case LXB_URL_ERROR_TYPE_FILE_INVALID_WINDOWS_DRIVE_LETTER_HOST:
213-
error_str = ZSTR_INIT_LITERAL("FileInvalidWindowsDriveLetterHost", false);
213+
error_str = "FileInvalidWindowsDriveLetterHost";
214214
ZVAL_FALSE(&failure);
215215
break;
216216
EMPTY_SWITCH_DEFAULT_CASE()
217217
}
218218

219219
zval error_type;
220-
zend_enum_new(&error_type, uri_whatwg_url_validation_error_type_ce, error_str, NULL);
220+
ZVAL_OBJ(&error_type, zend_enum_get_case_cstr(uri_whatwg_url_validation_error_type_ce, error_str));
221221
zend_update_property_ex(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZSTR_KNOWN(ZEND_STR_TYPE), &error_type);
222-
zend_string_release_ex(error_str, false);
223-
zval_ptr_dtor(&error_type);
224222

225223
zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("failure"), &failure);
226224

@@ -236,14 +234,14 @@ static zend_string *fill_errors(zval *errors)
236234

237235
static void throw_invalid_url_exception_during_write(zval *errors, const char *component)
238236
{
239-
zend_string *reason = fill_errors(errors);
237+
const char *reason = fill_errors(errors);
240238
zend_object *exception = zend_throw_exception_ex(
241239
uri_whatwg_invalid_url_exception_ce,
242240
0,
243241
"The specified %s is malformed%s%s%s",
244242
component,
245243
reason ? " (" : "",
246-
reason ? ZSTR_VAL(reason) : "",
244+
reason ? reason : "",
247245
reason ? ")" : ""
248246
);
249247
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors);
@@ -567,10 +565,10 @@ lxb_url_t *lexbor_parse_uri_ex(const zend_string *uri_str, const lxb_url_t *lexb
567565
lexbor_cleanup_parser();
568566

569567
lxb_url_t *url = lxb_url_parse(&lexbor_parser, lexbor_base_url, (unsigned char *) ZSTR_VAL(uri_str), ZSTR_LEN(uri_str));
570-
zend_string *reason = fill_errors(errors);
568+
const char *reason = fill_errors(errors);
571569

572570
if (url == NULL && !silent) {
573-
zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? ZSTR_VAL(reason) : "", reason ? ")" : "");
571+
zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? reason : "", reason ? ")" : "");
574572
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors);
575573
}
576574

‎ext/uri/tests/054.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Test UrlValidationErrorType singleton
3+
--EXTENSIONS--
4+
uri
5+
--FILE--
6+
<?php
7+
8+
try {
9+
new \Uri\WhatWg\Url('http://localhost:99999');
10+
} catch (Uri\WhatWg\InvalidUrlException $e) {
11+
echo $e->getMessage() . "\n";
12+
var_dump($e->errors[0]->type === \Uri\WhatWg\UrlValidationErrorType::PortOutOfRange);
13+
}
14+
15+
?>
16+
--EXPECT--
17+
The specified URI is malformed (PortOutOfRange)
18+
bool(true)

0 commit comments

Comments
 (0)