mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Fix OSS-Fuzz #428053935 (#18969)
Registering the constant may happen under another name due to lowercasing. This will cause the lookup to the constant to fail. Instead of looking it up, just change the Zend API to return a pointer instead.
This commit is contained in:
parent
db157e3168
commit
4a18c895ca
7 changed files with 34 additions and 16 deletions
|
@ -45,6 +45,8 @@ PHP 8.5 INTERNALS UPGRADE NOTES
|
|||
properties.
|
||||
. ZEND_IS_XDIGIT() macro was removed because it was unused and its name
|
||||
did not match its actual behavior.
|
||||
. zend_register_constant() now returns a pointer to the added constant
|
||||
on success and NULL on failure instead of SUCCESS/FAILURE.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
|
|
19
Zend/tests/attributes/constants/oss_fuzz_428053935.phpt
Normal file
19
Zend/tests/attributes/constants/oss_fuzz_428053935.phpt
Normal file
|
@ -0,0 +1,19 @@
|
|||
--TEST--
|
||||
OSS-Fuzz #428053935
|
||||
--FILE--
|
||||
<?php
|
||||
namespace Foo; // Capital letter is important for the ns lookup
|
||||
#[Attr]
|
||||
const MyConst = '';
|
||||
|
||||
$rc = new \ReflectionConstant('Foo\\MyConst');
|
||||
var_dump($rc->getAttributes());
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(ReflectionAttribute)#%d (1) {
|
||||
["name"]=>
|
||||
string(8) "Foo\Attr"
|
||||
}
|
||||
}
|
|
@ -592,7 +592,7 @@ register_constant:
|
|||
/* non persistent */
|
||||
ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
|
||||
c.name = zend_string_copy(name);
|
||||
if (zend_register_constant(&c) == SUCCESS) {
|
||||
if (zend_register_constant(&c) != NULL) {
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
|
|
|
@ -505,11 +505,11 @@ static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_consta
|
|||
return ret;
|
||||
}
|
||||
|
||||
ZEND_API zend_result zend_register_constant(zend_constant *c)
|
||||
ZEND_API zend_constant *zend_register_constant(zend_constant *c)
|
||||
{
|
||||
zend_string *lowercase_name = NULL;
|
||||
zend_string *name;
|
||||
zend_result ret = SUCCESS;
|
||||
zend_constant *ret = NULL;
|
||||
bool persistent = (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) != 0;
|
||||
|
||||
#if 0
|
||||
|
@ -539,7 +539,7 @@ ZEND_API zend_result zend_register_constant(zend_constant *c)
|
|||
/* Check if the user is trying to define any special constant */
|
||||
if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__")
|
||||
|| (!persistent && zend_get_special_const(ZSTR_VAL(name), ZSTR_LEN(name)))
|
||||
|| zend_hash_add_constant(EG(zend_constants), name, c) == NULL
|
||||
|| (ret = zend_hash_add_constant(EG(zend_constants), name, c)) == NULL
|
||||
) {
|
||||
zend_error(E_WARNING, "Constant %s already defined", ZSTR_VAL(name));
|
||||
zend_string_release(c->name);
|
||||
|
@ -550,7 +550,6 @@ ZEND_API zend_result zend_register_constant(zend_constant *c)
|
|||
if (!persistent) {
|
||||
zval_ptr_dtor_nogc(&c->value);
|
||||
}
|
||||
ret = FAILURE;
|
||||
}
|
||||
if (lowercase_name) {
|
||||
zend_string_release(lowercase_name);
|
||||
|
|
|
@ -97,7 +97,7 @@ ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zen
|
|||
ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number);
|
||||
ZEND_API void zend_register_string_constant(const char *name, size_t name_len, const char *strval, int flags, int module_number);
|
||||
ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, const char *strval, size_t strlen, int flags, int module_number);
|
||||
ZEND_API zend_result zend_register_constant(zend_constant *c);
|
||||
ZEND_API zend_constant *zend_register_constant(zend_constant *c);
|
||||
void zend_constant_add_attributes(zend_constant *c, HashTable *attributes);
|
||||
#ifdef ZTS
|
||||
void zend_copy_constants(HashTable *target, HashTable *source);
|
||||
|
|
|
@ -8261,7 +8261,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
|
|||
ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
|
||||
c.name = zend_string_copy(Z_STR_P(name));
|
||||
|
||||
if (zend_register_constant(&c) == FAILURE) {
|
||||
if (zend_register_constant(&c) == NULL) {
|
||||
}
|
||||
|
||||
FREE_OP1();
|
||||
|
@ -8274,7 +8274,7 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST)
|
|||
USE_OPLINE
|
||||
zval *name;
|
||||
zval *val;
|
||||
zend_constant c;
|
||||
zend_constant c, *registered;
|
||||
|
||||
SAVE_OPLINE();
|
||||
name = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
|
@ -8293,7 +8293,8 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST)
|
|||
ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
|
||||
c.name = zend_string_copy(Z_STR_P(name));
|
||||
|
||||
if (zend_register_constant(&c) == FAILURE) {
|
||||
registered = zend_register_constant(&c);
|
||||
if (registered == NULL) {
|
||||
FREE_OP1();
|
||||
FREE_OP2();
|
||||
/* two opcodes used, second one is the data with attributes */
|
||||
|
@ -8301,9 +8302,7 @@ ZEND_VM_HANDLER(210, ZEND_DECLARE_ATTRIBUTED_CONST, CONST, CONST)
|
|||
}
|
||||
|
||||
HashTable *attributes = Z_PTR_P(GET_OP_DATA_ZVAL_PTR(BP_VAR_R));
|
||||
zend_constant *registered = zend_get_constant_ptr(c.name);
|
||||
ZEND_ASSERT(attributes != NULL);
|
||||
ZEND_ASSERT(registered != NULL);
|
||||
zend_constant_add_attributes(registered, attributes);
|
||||
|
||||
FREE_OP1();
|
||||
|
|
9
Zend/zend_vm_execute.h
generated
9
Zend/zend_vm_execute.h
generated
|
@ -8043,7 +8043,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST
|
|||
ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
|
||||
c.name = zend_string_copy(Z_STR_P(name));
|
||||
|
||||
if (zend_register_constant(&c) == FAILURE) {
|
||||
if (zend_register_constant(&c) == NULL) {
|
||||
}
|
||||
|
||||
|
||||
|
@ -8055,7 +8055,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_
|
|||
USE_OPLINE
|
||||
zval *name;
|
||||
zval *val;
|
||||
zend_constant c;
|
||||
zend_constant c, *registered;
|
||||
|
||||
SAVE_OPLINE();
|
||||
name = RT_CONSTANT(opline, opline->op1);
|
||||
|
@ -8074,7 +8074,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_
|
|||
ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT);
|
||||
c.name = zend_string_copy(Z_STR_P(name));
|
||||
|
||||
if (zend_register_constant(&c) == FAILURE) {
|
||||
registered = zend_register_constant(&c);
|
||||
if (registered == NULL) {
|
||||
|
||||
|
||||
/* two opcodes used, second one is the data with attributes */
|
||||
|
@ -8082,9 +8083,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_
|
|||
}
|
||||
|
||||
HashTable *attributes = Z_PTR_P(get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1));
|
||||
zend_constant *registered = zend_get_constant_ptr(c.name);
|
||||
ZEND_ASSERT(attributes != NULL);
|
||||
ZEND_ASSERT(registered != NULL);
|
||||
zend_constant_add_attributes(registered, attributes);
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue