mirror of
https://github.com/php/php-src.git
synced 2024-11-27 03:44:07 +08:00
Implement backed enum coercion in http_build_query()
Fixes GH-15650 Closes GH-15704
This commit is contained in:
parent
7a8767fe62
commit
1b9568d354
3
NEWS
3
NEWS
@ -44,6 +44,9 @@ PHP NEWS
|
||||
. Fixed bug GH-15711 (SoapClient can't convert BackedEnum to scalar value).
|
||||
(nielsdos)
|
||||
|
||||
- Standard:
|
||||
. Add support for backed enums in http_build_query(). (ilutov)
|
||||
|
||||
12 Sep 2024, PHP 8.4.0beta5
|
||||
|
||||
- BCMath:
|
||||
|
@ -225,6 +225,7 @@ PHP 8.4 UPGRADE NOTES
|
||||
. php_uname() now throws ValueErrors on invalid inputs.
|
||||
. The "allowed_classes" option for unserialize() now throws TypeErrors and
|
||||
ValueErrors if it is not an array of class names.
|
||||
. http_build_query() now correctly handles backed enums.
|
||||
|
||||
- Tidy:
|
||||
. Failures in the constructor now throw exceptions rather than emitting
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "SAPI.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "basic_functions.h"
|
||||
#include "zend_enum.h"
|
||||
|
||||
static void php_url_encode_scalar(zval *scalar, smart_str *form_str,
|
||||
int encoding_type, zend_ulong index_int,
|
||||
@ -56,6 +57,7 @@ static void php_url_encode_scalar(zval *scalar, smart_str *form_str,
|
||||
}
|
||||
smart_str_appendc(form_str, '=');
|
||||
|
||||
try_again:
|
||||
switch (Z_TYPE_P(scalar)) {
|
||||
case IS_STRING: {
|
||||
zend_string *encoded_data;
|
||||
@ -90,6 +92,14 @@ static void php_url_encode_scalar(zval *scalar, smart_str *form_str,
|
||||
case IS_TRUE:
|
||||
smart_str_appendc(form_str, '1');
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
ZEND_ASSERT(Z_OBJCE_P(scalar)->ce_flags & ZEND_ACC_ENUM);
|
||||
if (Z_OBJCE_P(scalar)->enum_backing_type == IS_UNDEF) {
|
||||
zend_value_error("Unbacked enum %s cannot be converted to a string", ZSTR_VAL(Z_OBJCE_P(scalar)->name));
|
||||
return;
|
||||
}
|
||||
scalar = zend_enum_fetch_case_value(Z_OBJ_P(scalar));
|
||||
goto try_again;
|
||||
/* All possible types are either handled here or previously */
|
||||
EMPTY_SWITCH_DEFAULT_CASE();
|
||||
}
|
||||
@ -154,7 +164,9 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
|
||||
}
|
||||
|
||||
ZVAL_DEREF(zdata);
|
||||
if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) {
|
||||
if (Z_TYPE_P(zdata) == IS_ARRAY
|
||||
|| (Z_TYPE_P(zdata) == IS_OBJECT
|
||||
&& !(Z_OBJCE_P(zdata)->ce_flags & ZEND_ACC_ENUM))) {
|
||||
zend_string *new_prefix;
|
||||
if (key) {
|
||||
zend_string *encoded_key;
|
||||
@ -233,6 +245,11 @@ PHP_FUNCTION(http_build_query)
|
||||
Z_PARAM_LONG(enc_type)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(formdata) == IS_OBJECT && (Z_OBJCE_P(formdata)->ce_flags & ZEND_ACC_ENUM))) {
|
||||
zend_argument_type_error(1, "must be of type array, %s given", zend_zval_value_name(formdata));
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, /* key_prefix */ NULL, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL), arg_sep, (int)enc_type);
|
||||
|
||||
RETURN_STR(smart_str_extract(&formstr));
|
||||
|
36
ext/standard/tests/http/gh15650.phpt
Normal file
36
ext/standard/tests/http/gh15650.phpt
Normal file
@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
GH-15650: http_build_query() with enum
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
enum E1: string {
|
||||
case C = 'hello world!';
|
||||
}
|
||||
|
||||
enum E2: int {
|
||||
case C = 42;
|
||||
}
|
||||
|
||||
enum E3 {
|
||||
case C;
|
||||
}
|
||||
|
||||
echo http_build_query(['e1' => E1::C, 'e2' => E2::C]), "\n";
|
||||
|
||||
try {
|
||||
echo http_build_query(['e3' => E3::C]);
|
||||
} catch (Throwable $e) {
|
||||
echo get_class($e), ': ', $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
echo http_build_query(E1::C);
|
||||
} catch (Throwable $e) {
|
||||
echo get_class($e), ': ', $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
e1=hello+world%21&e2=42
|
||||
ValueError: Unbacked enum E3 cannot be converted to a string
|
||||
TypeError: http_build_query(): Argument #1 ($data) must be of type array, E1 given
|
Loading…
Reference in New Issue
Block a user