mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
This allows extensions that already know which parser to use and don't need the generic lookup facility to directly refer to the desired parser without needing to go through `php_uri_get_parser()` (which also requires allocating a `zend_string*`). Following php/php-src#20173 Related to php/php-src#19868
185 lines
5.5 KiB
C
185 lines
5.5 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| 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 <kocsismate@php.net> |
|
|
| Tim Düsterhus <timwolla@php.net> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#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 zend_string *decode_component(zend_string *in, php_uri_component_read_mode read_mode)
|
|
{
|
|
switch (read_mode) {
|
|
case PHP_URI_COMPONENT_READ_MODE_RAW:
|
|
return zend_string_copy(in);
|
|
case PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII:
|
|
case PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE: {
|
|
zend_string *out = zend_string_alloc(ZSTR_LEN(in), false);
|
|
|
|
ZSTR_LEN(out) = php_raw_url_decode_ex(ZSTR_VAL(out), ZSTR_VAL(in), ZSTR_LEN(in));
|
|
|
|
return out;
|
|
}
|
|
EMPTY_SWITCH_DEFAULT_CASE();
|
|
}
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_scheme_read(void *uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = uri;
|
|
|
|
if (parse_url_uri->scheme) {
|
|
ZVAL_STR(retval, decode_component(parse_url_uri->scheme, read_mode));
|
|
} else {
|
|
ZVAL_NULL(retval);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_username_read(void *uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = uri;
|
|
|
|
if (parse_url_uri->user) {
|
|
ZVAL_STR(retval, decode_component(parse_url_uri->user, read_mode));
|
|
} else {
|
|
ZVAL_NULL(retval);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_password_read(void *uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = uri;
|
|
|
|
if (parse_url_uri->pass) {
|
|
ZVAL_STR(retval, decode_component(parse_url_uri->pass, read_mode));
|
|
} else {
|
|
ZVAL_NULL(retval);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_host_read(void *uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = uri;
|
|
|
|
if (parse_url_uri->host) {
|
|
ZVAL_STR(retval, decode_component(parse_url_uri->host, read_mode));
|
|
} else {
|
|
ZVAL_NULL(retval);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_port_read(void *uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = uri;
|
|
|
|
if (parse_url_uri->port) {
|
|
ZVAL_LONG(retval, parse_url_uri->port);
|
|
} else {
|
|
ZVAL_NULL(retval);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_path_read(void *uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = uri;
|
|
|
|
if (parse_url_uri->path) {
|
|
ZVAL_STR(retval, decode_component(parse_url_uri->path, read_mode));
|
|
} else {
|
|
ZVAL_NULL(retval);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_query_read(void *uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = uri;
|
|
|
|
if (parse_url_uri->query) {
|
|
ZVAL_STR(retval, decode_component(parse_url_uri->query, read_mode));
|
|
} else {
|
|
ZVAL_NULL(retval);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_fragment_read(void *uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = uri;
|
|
|
|
if (parse_url_uri->fragment) {
|
|
ZVAL_STR(retval, decode_component(parse_url_uri->fragment, 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(php_uri_ce_invalid_uri_exception, "The specified URI is malformed", 0);
|
|
}
|
|
|
|
return url;
|
|
}
|
|
|
|
static void uri_parser_php_parse_url_destroy(void *uri)
|
|
{
|
|
php_url *parse_url_uri = uri;
|
|
|
|
if (UNEXPECTED(parse_url_uri == NULL)) {
|
|
return;
|
|
}
|
|
|
|
php_url_free(parse_url_uri);
|
|
}
|
|
|
|
PHPAPI const php_uri_parser php_uri_parser_php_parse_url = {
|
|
.name = PHP_URI_PARSER_PHP_PARSE_URL,
|
|
.parse = uri_parser_php_parse_url_parse,
|
|
.clone = NULL,
|
|
.to_string = NULL,
|
|
.destroy = uri_parser_php_parse_url_destroy,
|
|
{
|
|
.scheme = {.read = uri_parser_php_parse_url_scheme_read, .write = NULL},
|
|
.username = {.read = uri_parser_php_parse_url_username_read, .write = NULL},
|
|
.password = {.read = uri_parser_php_parse_url_password_read, .write = NULL},
|
|
.host = {.read = uri_parser_php_parse_url_host_read, .write = NULL},
|
|
.port = {.read = uri_parser_php_parse_url_port_read, .write = NULL},
|
|
.path = {.read = uri_parser_php_parse_url_path_read, .write = NULL},
|
|
.query = {.read = uri_parser_php_parse_url_query_read, .write = NULL},
|
|
.fragment = {.read = uri_parser_php_parse_url_fragment_read, .write = NULL},
|
|
}
|
|
};
|