Skip to content

uri: Improve exceptions for Uri\Rfc3986\Uri #19161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 18, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
78 changes: 47 additions & 31 deletions ext/uri/php_uriparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "Zend/zend_exceptions.h"

static void uriparser_free_uri(void *uri);
static void throw_invalid_uri_exception(void);

static void *uriparser_malloc(UriMemoryManager *memory_manager, size_t size)
{
Expand Down Expand Up @@ -293,51 +292,68 @@ static uriparser_uris_t *uriparser_create_uris(void)
return uriparser_uris;
}

static void throw_invalid_uri_exception(void)
void *uriparser_parse_uri_ex(const zend_string *uri_str, const uriparser_uris_t *uriparser_base_urls, bool silent)
{
zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI is malformed", 0);
}
UriUriA uri = {0};

#define PARSE_URI(dest_uri, uri_str, uriparser_uris, silent) \
do { \
if (ZSTR_LEN(uri_str) == 0 || \
uriParseSingleUriExMmA(dest_uri, ZSTR_VAL(uri_str), ZSTR_VAL(uri_str) + ZSTR_LEN(uri_str), NULL, mm) != URI_SUCCESS \
) { \
efree(uriparser_uris); \
if (!silent) { \
throw_invalid_uri_exception(); \
} \
return NULL; \
} \
} while (0)
/* Empty URIs are always invalid. */
if (ZSTR_LEN(uri_str) == 0) {
if (!silent) {
zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI must not be empty", 0);
}

void *uriparser_parse_uri_ex(const zend_string *uri_str, const uriparser_uris_t *uriparser_base_urls, bool silent)
{
uriparser_uris_t *uriparser_uris = uriparser_create_uris();
goto fail;
}

/* Parse the URI. */
if (uriParseSingleUriExMmA(&uri, ZSTR_VAL(uri_str), ZSTR_VAL(uri_str) + ZSTR_LEN(uri_str), NULL, mm) != URI_SUCCESS) {
if (!silent) {
zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI is malformed", 0);
}

if (uriparser_base_urls == NULL) {
PARSE_URI(&uriparser_uris->uri, uri_str, uriparser_uris, silent);
uriMakeOwnerMmA(&uriparser_uris->uri, mm);
} else {
UriUriA uri;
goto fail;
}

PARSE_URI(&uri, uri_str, uriparser_uris, silent);
if (uriparser_base_urls != NULL) {
UriUriA tmp = {0};

if (uriAddBaseUriExMmA(&uriparser_uris->uri, &uri, &uriparser_base_urls->uri, URI_RESOLVE_STRICTLY, mm) != URI_SUCCESS) {
efree(uriparser_uris);
uriFreeUriMembersMmA(&uri, mm);
/* Combine the parsed URI with the base URI and store the result in 'tmp',
* since the target and source URLs must be distinct. */
int result = uriAddBaseUriExMmA(&tmp, &uri, &uriparser_base_urls->uri, URI_RESOLVE_STRICTLY, mm);
if (result != URI_SUCCESS) {
if (!silent) {
throw_invalid_uri_exception();
switch (result) {
case URI_ERROR_ADDBASE_REL_BASE:
zend_throw_exception(uri_invalid_uri_exception_ce, "The specified base URI must be absolute", 0);
break;
default:
/* This should be unreachable in practice. */
zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to resolve the specified URI against the base URI", 0);
break;
}
}

return NULL;
goto fail;
}

uriMakeOwnerMmA(&uriparser_uris->uri, mm);
/* Store the combined URI back into 'uri'. */
uriFreeUriMembersMmA(&uri, mm);
uri = tmp;
}

/* Make the resulting URI independent of the 'uri_str'. */
uriMakeOwnerMmA(&uri, mm);

uriparser_uris_t *uriparser_uris = uriparser_create_uris();
uriparser_uris->uri = uri;

return uriparser_uris;

fail:

uriFreeUriMembersMmA(&uri, mm);

return NULL;
}

void *uriparser_parse_uri(const zend_string *uri_str, const void *base_url, zval *errors, bool silent)
Expand Down
2 changes: 1 addition & 1 deletion ext/uri/tests/004.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var_dump(Uri\WhatWg\Url::parse("http://RuPaul's Drag Race All Stars 7 Winners Ca

?>
--EXPECTF--
The specified URI is malformed
The specified URI must not be empty
NULL
The specified URI is malformed (MissingSchemeNonRelativeUrl)
NULL
Expand Down
2 changes: 1 addition & 1 deletion ext/uri/tests/055.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ try {
}
?>
--EXPECT--
The specified URI is malformed
The specified base URI must be absolute