diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 2c64de3f58724..c354b4aa29e20 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -630,7 +630,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ if ( /* Skipping these checks is possible because the new URI implementations perform comprehensive validations. */ - strcmp(uri_parser->name, URI_PARSER_PHP) == 0 && + strcmp(uri_parser->name, PHP_URI_PARSER_PHP_PARSE_URL) == 0 && /* An IPv6 enclosed by square brackets is a valid hostname.*/ !php_filter_is_valid_ipv6_hostname(uri->host) && /* Validate domain. @@ -651,7 +651,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ RETURN_VALIDATION_FAILED } - if (strcmp(uri_parser->name, URI_PARSER_PHP) == 0 && + if (strcmp(uri_parser->name, PHP_URI_PARSER_PHP_PARSE_URL) == 0 && ( (uri->user != NULL && !is_userinfo_valid(uri->user)) || (uri->password != NULL && !is_userinfo_valid(uri->password)) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index ee148ff6c9226..aa5c2a2cedfff 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -305,7 +305,6 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ BASIC_MINIT_SUBMODULE(user_filters) BASIC_MINIT_SUBMODULE(password) BASIC_MINIT_SUBMODULE(image) - BASIC_MINIT_SUBMODULE(url) #ifdef ZTS BASIC_MINIT_SUBMODULE(localeconv) diff --git a/ext/standard/url.c b/ext/standard/url.c index dfd5fa46ccc0c..504805484ef2c 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -25,8 +25,6 @@ #include "file.h" #include "zend_simd.h" #include "Zend/zend_smart_str.h" -#include "Zend/zend_exceptions.h" -#include "ext/uri/php_uri.h" /* {{{ free_url */ PHPAPI void php_url_free(php_url *theurl) @@ -49,13 +47,6 @@ PHPAPI void php_url_free(php_url *theurl) } /* }}} */ -static void parse_url_free_uri(void *uri) -{ - php_url *parse_url_uri = (php_url *) uri; - - php_url_free(parse_url_uri); -} - static void php_replace_controlchars(char *str, size_t len) { unsigned char *s = (unsigned char *)str; @@ -320,166 +311,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port return ret; } - -static void parse_url_decode_component(zval *zv, uri_component_read_mode_t read_mode) -{ - if (Z_TYPE_P(zv) != IS_STRING) { - return; - } - - if (read_mode == URI_COMPONENT_READ_RAW) { - return; - } - - php_raw_url_decode(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); -} - -static zend_result parse_url_read_scheme(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - php_url *parse_url_uri = internal_uri->uri; - - if (parse_url_uri->scheme) { - ZVAL_STR_COPY(retval, parse_url_uri->scheme); - parse_url_decode_component(retval, read_mode); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result parse_url_read_username(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - php_url *parse_url_uri = internal_uri->uri; - - if (parse_url_uri->user) { - ZVAL_STR_COPY(retval, parse_url_uri->user); - parse_url_decode_component(retval, read_mode); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result parse_url_read_password(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - php_url *parse_url_uri = internal_uri->uri; - - if (parse_url_uri->pass) { - ZVAL_STR_COPY(retval, parse_url_uri->pass); - parse_url_decode_component(retval, read_mode); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result parse_url_read_host(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - php_url *parse_url_uri = internal_uri->uri; - - if (parse_url_uri->host) { - ZVAL_STR_COPY(retval, parse_url_uri->host); - parse_url_decode_component(retval, read_mode); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result parse_url_read_port(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - php_url *parse_url_uri = internal_uri->uri; - - if (parse_url_uri->port) { - ZVAL_LONG(retval, parse_url_uri->port); - parse_url_decode_component(retval, read_mode); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result parse_url_read_path(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - php_url *parse_url_uri = internal_uri->uri; - - if (parse_url_uri->path) { - ZVAL_STR_COPY(retval, parse_url_uri->path); - parse_url_decode_component(retval, read_mode); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result parse_url_read_query(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - php_url *parse_url_uri = internal_uri->uri; - - if (parse_url_uri->query) { - ZVAL_STR_COPY(retval, parse_url_uri->query); - parse_url_decode_component(retval, read_mode); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static zend_result parse_url_read_fragment(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) -{ - php_url *parse_url_uri = internal_uri->uri; - - if (parse_url_uri->fragment) { - ZVAL_STR_COPY(retval, parse_url_uri->fragment); - parse_url_decode_component(retval, read_mode); - } else { - ZVAL_NULL(retval); - } - - return SUCCESS; -} - -static void throw_invalid_uri_exception(void) -{ - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI is malformed", 0); -} - -static void *parse_url_parse_uri(const char *uri_str, size_t uri_str_len, const void *base_url, zval *errors, bool silent) -{ - bool has_port; - - php_url *url = php_url_parse_ex2(uri_str, uri_str_len, &has_port); - if (url == NULL && !silent) { - throw_invalid_uri_exception(); - } - - return url; -} - -const uri_parser_t parse_url_uri_parser = { - .name = URI_PARSER_PHP, - .parse_uri = parse_url_parse_uri, - .clone_uri = NULL, - .uri_to_string = NULL, - .free_uri = parse_url_free_uri, - { - .scheme = {.read_func = parse_url_read_scheme, .write_func = NULL}, - .username = {.read_func = parse_url_read_username, .write_func = NULL}, - .password = {.read_func = parse_url_read_password, .write_func = NULL}, - .host = {.read_func = parse_url_read_host, .write_func = NULL}, - .port = {.read_func = parse_url_read_port, .write_func = NULL}, - .path = {.read_func = parse_url_read_path, .write_func = NULL}, - .query = {.read_func = parse_url_read_query, .write_func = NULL}, - .fragment = {.read_func = parse_url_read_fragment, .write_func = NULL}, - } -}; +/* }}} */ /* {{{ Parse a URL and return its components */ PHP_FUNCTION(parse_url) @@ -921,8 +753,3 @@ PHP_FUNCTION(get_headers) php_stream_close(stream); } /* }}} */ - -PHP_MINIT_FUNCTION(url) -{ - return php_uri_parser_register(&parse_url_uri_parser); -} diff --git a/ext/standard/url.h b/ext/standard/url.h index aefc362744cfd..3885ecece5780 100644 --- a/ext/standard/url.h +++ b/ext/standard/url.h @@ -17,8 +17,6 @@ #ifndef URL_H #define URL_H -PHP_MINIT_FUNCTION(url); - typedef struct php_url { zend_string *scheme; zend_string *user; diff --git a/ext/uri/config.m4 b/ext/uri/config.m4 index a43505e2ca9eb..8606b56705d55 100644 --- a/ext/uri/config.m4 +++ b/ext/uri/config.m4 @@ -6,6 +6,7 @@ PHP_INSTALL_HEADERS([ext/uri], m4_normalize([ php_uri_common.h uri_parser_rfc3986.h uri_parser_whatwg.h + uri_parser_php_parse_url.h ])) AC_DEFINE([URI_ENABLE_ANSI], [1], [Define to 1 for enabling ANSI support of uriparser.]) @@ -18,6 +19,6 @@ $URIPARSER_DIR/src/UriMemory.c $URIPARSER_DIR/src/UriNormalize.c $URIPARSER_DIR/ $URIPARSER_DIR/src/UriParse.c $URIPARSER_DIR/src/UriParseBase.c $URIPARSER_DIR/src/UriQuery.c \ $URIPARSER_DIR/src/UriRecompose.c $URIPARSER_DIR/src/UriResolve.c $URIPARSER_DIR/src/UriShorten.c" -PHP_NEW_EXTENSION(uri, [php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c $URIPARSER_SOURCES], [no],,[-I$ext_srcdir/$URIPARSER_DIR/include -DURI_STATIC_BUILD -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) +PHP_NEW_EXTENSION(uri, [php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c $URIPARSER_SOURCES], [no],,[-I$ext_srcdir/$URIPARSER_DIR/include -DURI_STATIC_BUILD -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1]) PHP_ADD_EXTENSION_DEP(uri, lexbor) PHP_ADD_BUILD_DIR($ext_builddir/$URIPARSER_DIR/src $ext_builddir/$URIPARSER_DIR/include) diff --git a/ext/uri/config.w32 b/ext/uri/config.w32 index c5ed6fdc17267..8d1452ccfb862 100644 --- a/ext/uri/config.w32 +++ b/ext/uri/config.w32 @@ -1,4 +1,4 @@ -EXTENSION("uri", "php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c ", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); +EXTENSION("uri", "php_uri.c php_uri_common.c uri_parser_rfc3986.c uri_parser_whatwg.c uri_parser_php_parse_url.c", false /* never shared */, "/I ext/lexbor /I ext/uri/uriparser/include /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); AC_DEFINE("URI_ENABLE_ANSI", 1, "Define to 1 for enabling ANSI support of uriparser.") AC_DEFINE("URI_NO_UNICODE", 1, "Define to 1 for disabling unicode support of uriparser.") @@ -6,4 +6,4 @@ ADD_FLAG("CFLAGS_URI", "/D URI_STATIC_BUILD"); ADD_EXTENSION_DEP('uri', 'lexbor'); ADD_SOURCES("ext/uri/uriparser/src", "UriCommon.c UriCompare.c UriCopy.c UriEscape.c UriFile.c UriIp4.c UriIp4Base.c UriMemory.c UriNormalize.c UriNormalizeBase.c UriParse.c UriParseBase.c UriQuery.c UriRecompose.c UriResolve.c UriShorten.c", "uri"); -PHP_INSTALL_HEADERS("ext/uri", "php_uri.h php_uri_common.h uri_parser_rfc3986.h uri_parser_whatwg.h uriparser/src uriparser/include"); +PHP_INSTALL_HEADERS("ext/uri", "php_uri.h php_uri_common.h uri_parser_rfc3986.h uri_parser_whatwg.h uri_parser_php_parse_url.h uriparser/src uriparser/include"); diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index e440ba8b8829c..bfbe34a9699f1 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -28,6 +28,7 @@ #include "php_uri.h" #include "uri_parser_whatwg.h" #include "uri_parser_rfc3986.h" +#include "uri_parser_php_parse_url.h" #include "php_uri_arginfo.h" #include "uriparser/src/UriConfig.h" @@ -109,7 +110,7 @@ static HashTable *uri_get_debug_properties(zend_object *object) PHPAPI uri_parser_t *php_uri_get_parser(const zend_string *uri_parser_name) { if (uri_parser_name == NULL) { - return uri_parser_by_name(URI_PARSER_PHP, sizeof(URI_PARSER_PHP) - 1); + return uri_parser_by_name(PHP_URI_PARSER_PHP_PARSE_URL, sizeof(PHP_URI_PARSER_PHP_PARSE_URL) - 1); } return uri_parser_by_name(ZSTR_VAL(uri_parser_name), ZSTR_LEN(uri_parser_name)); @@ -1021,8 +1022,8 @@ PHPAPI zend_result php_uri_parser_register(const uri_parser_t *uri_parser) ZEND_ASSERT(uri_parser->name != NULL); ZEND_ASSERT(uri_parser->parse_uri != NULL); - ZEND_ASSERT(uri_parser->clone_uri != NULL || strcmp(uri_parser->name, URI_PARSER_PHP) == 0); - ZEND_ASSERT(uri_parser->uri_to_string != NULL || strcmp(uri_parser->name, URI_PARSER_PHP) == 0); + ZEND_ASSERT(uri_parser->clone_uri != NULL || strcmp(uri_parser->name, PHP_URI_PARSER_PHP_PARSE_URL) == 0); + ZEND_ASSERT(uri_parser->uri_to_string != NULL || strcmp(uri_parser->name, PHP_URI_PARSER_PHP_PARSE_URL) == 0); ZEND_ASSERT(uri_parser->free_uri != NULL); zend_result result = zend_hash_add_ptr(&uri_parsers, key, (void *) uri_parser) != NULL ? SUCCESS : FAILURE; @@ -1057,6 +1058,10 @@ static PHP_MINIT_FUNCTION(uri) return FAILURE; } + if (php_uri_parser_register(&php_uri_parser_php_parse_url) == FAILURE) { + return FAILURE; + } + return SUCCESS; } diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index afffdfb8f5cf0..fb465bed502ab 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -164,7 +164,7 @@ static inline uri_internal_t *uri_internal_from_obj(const zend_object *object) { #define PHP_URI_PARSER_RFC3986 "Uri\\Rfc3986\\Uri" #define PHP_URI_PARSER_WHATWG "Uri\\WhatWg\\Url" -#define URI_PARSER_PHP "parse_url" +#define PHP_URI_PARSER_PHP_PARSE_URL "parse_url" #define URI_SERIALIZED_PROPERTY_NAME "uri" const uri_property_handler_t *uri_property_handler_from_internal_uri(const uri_internal_t *internal_uri, uri_property_name_t property_name); diff --git a/ext/uri/uri_parser_php_parse_url.c b/ext/uri/uri_parser_php_parse_url.c new file mode 100644 index 0000000000000..ae950ed48885e --- /dev/null +++ b/ext/uri/uri_parser_php_parse_url.c @@ -0,0 +1,184 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + | Tim Düsterhus | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" +#include "uri_parser_php_parse_url.h" +#include "php_uri_common.h" +#include "Zend/zend_exceptions.h" +#include "ext/standard/url.h" + +static void decode_component(zval *zv, uri_component_read_mode_t read_mode) +{ + if (Z_TYPE_P(zv) != IS_STRING) { + return; + } + + if (read_mode == URI_COMPONENT_READ_RAW) { + return; + } + + php_raw_url_decode(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); +} + +static zend_result uri_parser_php_parse_url_scheme_read(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + const php_url *parse_url_uri = internal_uri->uri; + + if (parse_url_uri->scheme) { + ZVAL_STR_COPY(retval, parse_url_uri->scheme); + decode_component(retval, read_mode); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static zend_result uri_parser_php_parse_url_username_read(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + const php_url *parse_url_uri = internal_uri->uri; + + if (parse_url_uri->user) { + ZVAL_STR_COPY(retval, parse_url_uri->user); + decode_component(retval, read_mode); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static zend_result uri_parser_php_parse_url_password_read(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + const php_url *parse_url_uri = internal_uri->uri; + + if (parse_url_uri->pass) { + ZVAL_STR_COPY(retval, parse_url_uri->pass); + decode_component(retval, read_mode); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static zend_result uri_parser_php_parse_url_host_read(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + const php_url *parse_url_uri = internal_uri->uri; + + if (parse_url_uri->host) { + ZVAL_STR_COPY(retval, parse_url_uri->host); + decode_component(retval, read_mode); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static zend_result uri_parser_php_parse_url_port_read(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + const php_url *parse_url_uri = internal_uri->uri; + + if (parse_url_uri->port) { + ZVAL_LONG(retval, parse_url_uri->port); + decode_component(retval, read_mode); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static zend_result uri_parser_php_parse_url_path_read(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + const php_url *parse_url_uri = internal_uri->uri; + + if (parse_url_uri->path) { + ZVAL_STR_COPY(retval, parse_url_uri->path); + decode_component(retval, read_mode); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static zend_result uri_parser_php_parse_url_query_read(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + const php_url *parse_url_uri = internal_uri->uri; + + if (parse_url_uri->query) { + ZVAL_STR_COPY(retval, parse_url_uri->query); + decode_component(retval, read_mode); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static zend_result uri_parser_php_parse_url_fragment_read(const uri_internal_t *internal_uri, uri_component_read_mode_t read_mode, zval *retval) +{ + const php_url *parse_url_uri = internal_uri->uri; + + if (parse_url_uri->fragment) { + ZVAL_STR_COPY(retval, parse_url_uri->fragment); + decode_component(retval, read_mode); + } else { + ZVAL_NULL(retval); + } + + return SUCCESS; +} + +static void *uri_parser_php_parse_url_parse(const char *uri_str, size_t uri_str_len, const void *base_url, zval *errors, bool silent) +{ + bool has_port; + + php_url *url = php_url_parse_ex2(uri_str, uri_str_len, &has_port); + if (url == NULL && !silent) { + zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI is malformed", 0); + } + + return url; +} + +static void uri_parser_php_parse_url_free(void *uri) +{ + php_url *parse_url_uri = uri; + + php_url_free(parse_url_uri); +} + +const uri_parser_t php_uri_parser_php_parse_url = { + .name = PHP_URI_PARSER_PHP_PARSE_URL, + .parse_uri = uri_parser_php_parse_url_parse, + .clone_uri = NULL, + .uri_to_string = NULL, + .free_uri = uri_parser_php_parse_url_free, + { + .scheme = {.read_func = uri_parser_php_parse_url_scheme_read, .write_func = NULL}, + .username = {.read_func = uri_parser_php_parse_url_username_read, .write_func = NULL}, + .password = {.read_func = uri_parser_php_parse_url_password_read, .write_func = NULL}, + .host = {.read_func = uri_parser_php_parse_url_host_read, .write_func = NULL}, + .port = {.read_func = uri_parser_php_parse_url_port_read, .write_func = NULL}, + .path = {.read_func = uri_parser_php_parse_url_path_read, .write_func = NULL}, + .query = {.read_func = uri_parser_php_parse_url_query_read, .write_func = NULL}, + .fragment = {.read_func = uri_parser_php_parse_url_fragment_read, .write_func = NULL}, + } +}; diff --git a/ext/uri/uri_parser_php_parse_url.h b/ext/uri/uri_parser_php_parse_url.h new file mode 100644 index 0000000000000..ef98088a26c45 --- /dev/null +++ b/ext/uri/uri_parser_php_parse_url.h @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + | Tim Düsterhus | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_URI_PARSER_PHP_PARSE_URL_H +#define PHP_URI_PARSER_PHP_PARSE_URL_H + +#include "php_uri_common.h" + +extern const uri_parser_t php_uri_parser_php_parse_url; + +#endif