mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
ext/spl: Throw TypeError when overloaded SplObjectStorage::getHash() method does not return a string
This commit is contained in:
parent
610c7a07b1
commit
a648365fc0
2 changed files with 47 additions and 42 deletions
|
@ -87,20 +87,21 @@ static zend_result spl_object_storage_get_hash(zend_hash_key *key, spl_SplObject
|
||||||
zval param;
|
zval param;
|
||||||
zval rv;
|
zval rv;
|
||||||
ZVAL_OBJ(¶m, obj);
|
ZVAL_OBJ(¶m, obj);
|
||||||
zend_call_method_with_1_params(
|
zend_call_method_with_1_params(&intern->std, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, ¶m);
|
||||||
&intern->std, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, ¶m);
|
if (UNEXPECTED(Z_ISUNDEF(rv))) {
|
||||||
if (!Z_ISUNDEF(rv)) {
|
/* An exception has occurred */
|
||||||
if (Z_TYPE(rv) == IS_STRING) {
|
return FAILURE;
|
||||||
key->key = Z_STR(rv);
|
} else {
|
||||||
return SUCCESS;
|
/* TODO PHP 9: Remove this as this will be enforced from the return type */
|
||||||
} else {
|
if (UNEXPECTED(Z_TYPE(rv) != IS_STRING)) {
|
||||||
zend_throw_exception(spl_ce_RuntimeException, "Hash needs to be a string", 0);
|
zend_type_error("%s::getHash(): Return value must be of type string, %s returned",
|
||||||
|
ZSTR_VAL(intern->std.ce->name), zend_zval_value_name(&rv));
|
||||||
zval_ptr_dtor(&rv);
|
zval_ptr_dtor(&rv);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
|
} else {
|
||||||
|
key->key = Z_STR(rv);
|
||||||
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
key->key = NULL;
|
key->key = NULL;
|
||||||
|
|
|
@ -1,27 +1,15 @@
|
||||||
--TEST--
|
--TEST--
|
||||||
SplObjectStorage::getHash implementation
|
SplObjectStorage::getHash() implementation
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$s = new SplObjectStorage();
|
|
||||||
$o1 = new Stdclass;
|
|
||||||
$o2 = new Stdclass;
|
|
||||||
$s[$o1] = "some_value\n";
|
|
||||||
echo $s->offsetGet($o1);
|
|
||||||
|
|
||||||
class MySplObjectStorage extends SplObjectStorage {
|
class MySplObjectStorage1 extends SplObjectStorage {
|
||||||
#[ReturnTypeWillChange]
|
#[ReturnTypeWillChange]
|
||||||
public function getHash($obj) {
|
public function getHash($obj) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
$s1 = new MySplObjectStorage;
|
|
||||||
$s1[$o1] = "foo";
|
|
||||||
} catch(Exception $e) {
|
|
||||||
echo "caught 1\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
class MySplObjectStorage2 extends SplObjectStorage {
|
class MySplObjectStorage2 extends SplObjectStorage {
|
||||||
public function getHash($obj): string {
|
public function getHash($obj): string {
|
||||||
throw new Exception("foo");
|
throw new Exception("foo");
|
||||||
|
@ -29,31 +17,47 @@ class MySplObjectStorage2 extends SplObjectStorage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
$s2 = new MySplObjectStorage2;
|
|
||||||
$s2[$o2] = "foo";
|
|
||||||
} catch(Exception $e) {
|
|
||||||
echo "caught 2\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
class MySplObjectStorage3 extends SplObjectStorage {
|
class MySplObjectStorage3 extends SplObjectStorage {
|
||||||
public function getHash($obj): string {
|
public function getHash($obj): string {
|
||||||
return "asd";
|
return "asd";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$s3 = new MySplObjectStorage3;
|
$s = new SplObjectStorage();
|
||||||
$s3[$o1] = $o1;
|
$o1 = new stdClass();
|
||||||
var_dump($s3[$o1]);
|
$o2 = new stdClass();
|
||||||
$s3[$o2] = $o2;
|
|
||||||
|
|
||||||
var_dump($s3[$o1] === $s3[$o2]);
|
$instances = [
|
||||||
|
new SplObjectStorage(),
|
||||||
|
new MySplObjectStorage1(),
|
||||||
|
new MySplObjectStorage2(),
|
||||||
|
new MySplObjectStorage3(),
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($instances as $instance) {
|
||||||
|
echo 'Instance as ', $instance::class, PHP_EOL;
|
||||||
|
try {
|
||||||
|
$instance[$o1] = 'foo';
|
||||||
|
var_dump($instance->offsetGet($o1));
|
||||||
|
var_dump($instance[$o1]);
|
||||||
|
$instance[$o2] = $o2;
|
||||||
|
var_dump($instance[$o1] === $instance[$o2]);
|
||||||
|
} catch(Throwable $e) {
|
||||||
|
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
some_value
|
Instance as SplObjectStorage
|
||||||
caught 1
|
string(3) "foo"
|
||||||
caught 2
|
string(3) "foo"
|
||||||
object(stdClass)#2 (0) {
|
bool(false)
|
||||||
}
|
Instance as MySplObjectStorage1
|
||||||
|
TypeError: MySplObjectStorage1::getHash(): Return value must be of type string, int returned
|
||||||
|
Instance as MySplObjectStorage2
|
||||||
|
Exception: foo
|
||||||
|
Instance as MySplObjectStorage3
|
||||||
|
string(3) "foo"
|
||||||
|
string(3) "foo"
|
||||||
bool(true)
|
bool(true)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue