Skip to content

Commit 8cdd2c8

Browse files
committed
uri: Remove php_uri_parse() and php_uri_free()
This API is both less powerful as well as less efficient compared to just calling the `->parse_uri()` handler of the parser directly. With regard to efficiency it needlessly allocates 32 byte of memory to store two pointers, of which one is already known, because it's the input. While it would be possible to just return the resulting `uri_internal_t` struct (instead of a pointer to a freshly allocated one), which would be returned as a register pair, users of the API can also just create the struct themselves for even more flexibility in allocations. The API is also less powerful, because it does not support base URIs.
1 parent a9f7388 commit 8cdd2c8

File tree

4 files changed

+57
-69
lines changed

4 files changed

+57
-69
lines changed

ext/openssl/xp_ssl.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2640,14 +2640,19 @@ static char *php_openssl_get_url_name(const char *resourcename,
26402640
return NULL;
26412641
}
26422642

2643-
uri_internal_t *internal_uri = php_uri_parse(uri_parser, resourcename, resourcenamelen, true);
2644-
if (internal_uri == NULL) {
2643+
void *parsed = uri_parser->parse(resourcename, resourcenamelen,
2644+
/* base_url */ NULL, /* errors */ NULL, /* silent */ true);
2645+
if (parsed == NULL) {
26452646
return NULL;
26462647
}
2648+
uri_internal_t internal_uri = {
2649+
.parser = uri_parser,
2650+
.uri = parsed,
2651+
};
26472652

26482653
char * url_name = NULL;
26492654
zval host_zv;
2650-
zend_result result = php_uri_get_host(internal_uri, PHP_URI_COMPONENT_READ_MODE_RAW, &host_zv);
2655+
zend_result result = php_uri_get_host(&internal_uri, PHP_URI_COMPONENT_READ_MODE_RAW, &host_zv);
26512656
if (result == SUCCESS && Z_TYPE(host_zv) == IS_STRING) {
26522657
const char * host = Z_STRVAL(host_zv);
26532658
size_t len = Z_STRLEN(host_zv);
@@ -2662,7 +2667,7 @@ static char *php_openssl_get_url_name(const char *resourcename,
26622667
}
26632668
}
26642669

2665-
php_uri_free(internal_uri);
2670+
uri_parser->free(parsed);
26662671
zval_ptr_dtor(&host_zv);
26672672

26682673
return url_name;

ext/uri/php_uri.c

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,6 @@ PHPAPI const php_uri_parser *php_uri_get_parser(zend_string *uri_parser_name)
111111
return zend_hash_find_ptr(&uri_parsers, uri_parser_name);
112112
}
113113

114-
ZEND_ATTRIBUTE_NONNULL PHPAPI uri_internal_t *php_uri_parse(const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, bool silent)
115-
{
116-
void *parsed = uri_parser->parse(uri_str, uri_str_len, NULL, NULL, silent);
117-
118-
if (parsed == NULL) {
119-
return NULL;
120-
}
121-
122-
uri_internal_t *internal_uri = emalloc(sizeof(*internal_uri));
123-
internal_uri->parser = uri_parser;
124-
internal_uri->uri = parsed;
125-
126-
return internal_uri;
127-
}
128-
129114
ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_scheme(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv)
130115
{
131116
return internal_uri->parser->property_handler.scheme.read(internal_uri->uri, read_mode, zv);
@@ -166,96 +151,95 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_fragment(const uri_interna
166151
return internal_uri->parser->property_handler.fragment.read(internal_uri->uri, read_mode, zv);
167152
}
168153

169-
ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(uri_internal_t *internal_uri)
170-
{
171-
internal_uri->parser->destroy(internal_uri->uri);
172-
internal_uri->uri = NULL;
173-
internal_uri->parser = NULL;
174-
efree(internal_uri);
175-
}
176-
177154
ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri *php_uri_parse_to_struct(
178155
const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, php_uri_component_read_mode read_mode, bool silent
179156
) {
180-
uri_internal_t *uri_internal = php_uri_parse(uri_parser, uri_str, uri_str_len, silent);
181-
if (uri_internal == NULL) {
157+
void *parsed = uri_parser->parse(uri_str, uri_str_len,
158+
/* base_url */ NULL, /* errors */ NULL, silent);
159+
if (parsed == NULL) {
182160
return NULL;
183161
}
184162

163+
uri_internal_t uri_internal = {
164+
.parser = uri_parser,
165+
.uri = parsed,
166+
};
167+
185168
php_uri *uri = ecalloc(1, sizeof(*uri));
186169
zval tmp;
187170
zend_result result;
188171

189-
result = php_uri_get_scheme(uri_internal, read_mode, &tmp);
172+
result = php_uri_get_scheme(&uri_internal, read_mode, &tmp);
190173
if (result == FAILURE) {
191174
goto error;
192175
}
193176
if (Z_TYPE(tmp) == IS_STRING) {
194177
uri->scheme = Z_STR(tmp);
195178
}
196179

197-
result = php_uri_get_username(uri_internal, read_mode, &tmp);
180+
result = php_uri_get_username(&uri_internal, read_mode, &tmp);
198181
if (result == FAILURE) {
199182
goto error;
200183
}
201184
if (Z_TYPE(tmp) == IS_STRING) {
202185
uri->user = Z_STR(tmp);
203186
}
204187

205-
result = php_uri_get_password(uri_internal, read_mode, &tmp);
188+
result = php_uri_get_password(&uri_internal, read_mode, &tmp);
206189
if (result == FAILURE) {
207190
goto error;
208191
}
209192
if (Z_TYPE(tmp) == IS_STRING) {
210193
uri->password = Z_STR(tmp);
211194
}
212195

213-
result = php_uri_get_host(uri_internal, read_mode, &tmp);
196+
result = php_uri_get_host(&uri_internal, read_mode, &tmp);
214197
if (result == FAILURE) {
215198
goto error;
216199
}
217200
if (Z_TYPE(tmp) == IS_STRING) {
218201
uri->host = Z_STR(tmp);
219202
}
220203

221-
result = php_uri_get_port(uri_internal, read_mode, &tmp);
204+
result = php_uri_get_port(&uri_internal, read_mode, &tmp);
222205
if (result == FAILURE) {
223206
goto error;
224207
}
225208
if (Z_TYPE(tmp) == IS_LONG) {
226209
uri->port = Z_LVAL(tmp);
227210
}
228211

229-
result = php_uri_get_path(uri_internal, read_mode, &tmp);
212+
result = php_uri_get_path(&uri_internal, read_mode, &tmp);
230213
if (result == FAILURE) {
231214
goto error;
232215
}
233216
if (Z_TYPE(tmp) == IS_STRING) {
234217
uri->path = Z_STR(tmp);
235218
}
236219

237-
result = php_uri_get_query(uri_internal, read_mode, &tmp);
220+
result = php_uri_get_query(&uri_internal, read_mode, &tmp);
238221
if (result == FAILURE) {
239222
goto error;
240223
}
241224
if (Z_TYPE(tmp) == IS_STRING) {
242225
uri->query = Z_STR(tmp);
243226
}
244227

245-
result = php_uri_get_fragment(uri_internal, read_mode, &tmp);
228+
result = php_uri_get_fragment(&uri_internal, read_mode, &tmp);
246229
if (result == FAILURE) {
247230
goto error;
248231
}
249232
if (Z_TYPE(tmp) == IS_STRING) {
250233
uri->fragment = Z_STR(tmp);
251234
}
252235

253-
php_uri_free(uri_internal);
236+
uri_parser->destroy(parsed);
254237

255238
return uri;
256239

257240
error:
258-
php_uri_free(uri_internal);
241+
242+
uri_parser->destroy(parsed);
259243
php_uri_struct_free(uri);
260244

261245
return NULL;
@@ -352,7 +336,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
352336
base_url = internal_base_url->uri;
353337
}
354338

355-
void *uri = uri_parser->parse(ZSTR_VAL(uri_str), ZSTR_LEN(uri_str), base_url, errors_zv != NULL ? &errors : NULL, !should_throw);
339+
void *uri = uri_parser->parse(ZSTR_VAL(uri_str), ZSTR_LEN(uri_str),
340+
base_url, errors_zv != NULL ? &errors : NULL, !should_throw);
356341
if (UNEXPECTED(uri == NULL)) {
357342
if (should_throw) {
358343
zval_ptr_dtor(&errors);
@@ -857,7 +842,8 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS)
857842
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name));
858843
RETURN_THROWS();
859844
}
860-
internal_uri->uri = internal_uri->parser->parse(Z_STRVAL_P(uri_zv), Z_STRLEN_P(uri_zv), NULL, NULL, true);
845+
internal_uri->uri = internal_uri->parser->parse(Z_STRVAL_P(uri_zv), Z_STRLEN_P(uri_zv),
846+
/* base_url */ NULL, /* errors */ NULL, /* silent */ true);
861847
if (internal_uri->uri == NULL) {
862848
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(object->ce->name));
863849
RETURN_THROWS();

ext/uri/php_uri.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ PHPAPI zend_result php_uri_parser_register(const php_uri_parser *uri_parser);
4949
*/
5050
PHPAPI const php_uri_parser *php_uri_get_parser(zend_string *uri_parser_name);
5151

52-
ZEND_ATTRIBUTE_NONNULL PHPAPI uri_internal_t *php_uri_parse(const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, bool silent);
53-
5452
/**
5553
* Retrieves the scheme component based on the read_mode and passes it to the zv ZVAL in case of success.
5654
*
@@ -171,13 +169,6 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_query(const uri_internal_t
171169
*/
172170
ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_fragment(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv);
173171

174-
/**
175-
* Frees the uri member within the provided internal URI.
176-
*
177-
* @param internal_uri The internal URI
178-
*/
179-
ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(uri_internal_t *internal_uri);
180-
181172
/**
182173
* Creates a new php_uri struct containing all the URI components. The components are retrieved based on the read_mode parameter.
183174
*

ext/zend_test/test.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -741,54 +741,60 @@ static ZEND_FUNCTION(zend_test_uri_parser)
741741
RETURN_THROWS();
742742
}
743743

744-
uri_internal_t *uri = php_uri_parse(parser, ZSTR_VAL(uri_string), ZSTR_LEN(uri_string), false);
745-
if (uri == NULL) {
744+
void *parsed = parser->parse(ZSTR_VAL(uri_string), ZSTR_LEN(uri_string),
745+
/* base_url */ NULL, /* errors */ NULL, /* silent */ false);
746+
if (parsed == NULL) {
746747
RETURN_THROWS();
747748
}
748749

750+
uri_internal_t uri = {
751+
.parser = parser,
752+
.uri = parsed,
753+
};
754+
749755
zval value;
750756

751757
array_init(return_value);
752758
zval normalized;
753759
array_init(&normalized);
754-
php_uri_get_scheme(uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
760+
php_uri_get_scheme(&uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
755761
zend_hash_add(Z_ARR(normalized), ZSTR_KNOWN(ZEND_STR_SCHEME), &value);
756-
php_uri_get_username(uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
762+
php_uri_get_username(&uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
757763
zend_hash_add(Z_ARR(normalized), ZSTR_KNOWN(ZEND_STR_USERNAME), &value);
758-
php_uri_get_password(uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
764+
php_uri_get_password(&uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
759765
zend_hash_add(Z_ARR(normalized), ZSTR_KNOWN(ZEND_STR_PASSWORD), &value);
760-
php_uri_get_host(uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
766+
php_uri_get_host(&uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
761767
zend_hash_add(Z_ARR(normalized), ZSTR_KNOWN(ZEND_STR_HOST), &value);
762-
php_uri_get_port(uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
768+
php_uri_get_port(&uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
763769
zend_hash_add(Z_ARR(normalized), ZSTR_KNOWN(ZEND_STR_PORT), &value);
764-
php_uri_get_path(uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
770+
php_uri_get_path(&uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
765771
zend_hash_add(Z_ARR(normalized), ZSTR_KNOWN(ZEND_STR_PATH), &value);
766-
php_uri_get_query(uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
772+
php_uri_get_query(&uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
767773
zend_hash_add(Z_ARR(normalized), ZSTR_KNOWN(ZEND_STR_QUERY), &value);
768-
php_uri_get_fragment(uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
774+
php_uri_get_fragment(&uri, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII, &value);
769775
zend_hash_add(Z_ARR(normalized), ZSTR_KNOWN(ZEND_STR_FRAGMENT), &value);
770776
zend_hash_str_add(Z_ARR_P(return_value), "normalized", strlen("normalized"), &normalized);
771777
zval raw;
772778
array_init(&raw);
773-
php_uri_get_scheme(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
779+
php_uri_get_scheme(&uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
774780
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_SCHEME), &value);
775-
php_uri_get_username(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
781+
php_uri_get_username(&uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
776782
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_USERNAME), &value);
777-
php_uri_get_password(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
783+
php_uri_get_password(&uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
778784
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_PASSWORD), &value);
779-
php_uri_get_host(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
785+
php_uri_get_host(&uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
780786
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_HOST), &value);
781-
php_uri_get_port(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
787+
php_uri_get_port(&uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
782788
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_PORT), &value);
783-
php_uri_get_path(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
789+
php_uri_get_path(&uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
784790
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_PATH), &value);
785-
php_uri_get_query(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
791+
php_uri_get_query(&uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
786792
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_QUERY), &value);
787-
php_uri_get_fragment(uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
793+
php_uri_get_fragment(&uri, PHP_URI_COMPONENT_READ_MODE_RAW, &value);
788794
zend_hash_add(Z_ARR(raw), ZSTR_KNOWN(ZEND_STR_FRAGMENT), &value);
789795
zend_hash_str_add(Z_ARR_P(return_value), "raw", strlen("raw"), &raw);
790796

791-
php_uri_free(uri);
797+
parser->destroy(parsed);
792798
}
793799

794800
static bool has_opline(zend_execute_data *execute_data)

0 commit comments

Comments
 (0)