mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
* uri: Rename `uri_recomposition_mode_t` to `php_uri_recomposition_mode` * uri: Align the names of the `php_uri_recomposition_mode` values * uri: Rename `uri_component_read_mode_t` to `php_uri_component_read_mode` * uri: Align the names of the `php_uri_component_read_mode` values * uri: Rename `uri_property_name_t` to `php_uri_property_name` * uri: Align the names of the `php_uri_property_name` values * uri: Rename `uri_property_handler_t` to `php_uri_property_handler` * uri: Rename `uri_(read|write)_t` to `php_uri_property_handler_(read|write)` * uri: Rename `php_uri_property_handler`’s `(read|write)_func` to `read|write` The `_func` is implied by the data type and the name of the struct. * uri: Rename `uri_parser_t` to `php_uri_parser` * uri: Shorten the names of `php_uri_parser` fields The `_uri` suffix is implied, because this is an URI parser.
185 lines
5.7 KiB
C
185 lines
5.7 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(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = internal_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(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = internal_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(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = internal_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(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = internal_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(const uri_internal_t *internal_uri, php_uri_component_read_mode 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);
|
|
} else {
|
|
ZVAL_NULL(retval);
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
static zend_result uri_parser_php_parse_url_path_read(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = internal_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(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = internal_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(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *retval)
|
|
{
|
|
const php_url *parse_url_uri = internal_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(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;
|
|
|
|
if (UNEXPECTED(parse_url_uri == NULL)) {
|
|
return;
|
|
}
|
|
|
|
php_url_free(parse_url_uri);
|
|
}
|
|
|
|
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,
|
|
.free = uri_parser_php_parse_url_free,
|
|
{
|
|
.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},
|
|
}
|
|
};
|