mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix reference type confusion and leak in user random engine
Closes GH-18718. Co-authored-by: Tim Düsterhus <timwolla@googlemail.com>
This commit is contained in:
4
NEWS
4
NEWS
@@ -26,6 +26,10 @@ PHP NEWS
|
||||
. Fix warning not being emitted when failure to cancel a query with
|
||||
pg_cancel_query(). (Girgias)
|
||||
|
||||
- Random:
|
||||
. Fix reference type confusion and leak in user random engine.
|
||||
(nielsdos, timwolla)
|
||||
|
||||
- Readline:
|
||||
. Fix memory leak when calloc() fails in php_readline_completion_cb().
|
||||
(nielsdos)
|
||||
|
||||
@@ -27,6 +27,7 @@ static uint64_t generate(php_random_status *status)
|
||||
uint64_t result = 0;
|
||||
size_t size;
|
||||
zval retval;
|
||||
zend_string *zstr;
|
||||
|
||||
zend_call_known_instance_method_with_0_params(s->generate_method, s->object, &retval);
|
||||
|
||||
@@ -34,8 +35,14 @@ static uint64_t generate(php_random_status *status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (UNEXPECTED(Z_ISREF(retval))) {
|
||||
zstr = Z_STR_P(Z_REFVAL(retval));
|
||||
} else {
|
||||
zstr = Z_STR(retval);
|
||||
}
|
||||
|
||||
/* Store generated size in a state */
|
||||
size = Z_STRLEN(retval);
|
||||
size = ZSTR_LEN(zstr);
|
||||
|
||||
/* Guard for over 64-bit results */
|
||||
if (size > sizeof(uint64_t)) {
|
||||
@@ -46,11 +53,10 @@ static uint64_t generate(php_random_status *status)
|
||||
if (size > 0) {
|
||||
/* Endianness safe copy */
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
result += ((uint64_t) (unsigned char) Z_STRVAL(retval)[i]) << (8 * i);
|
||||
result += ((uint64_t) (unsigned char) ZSTR_VAL(zstr)[i]) << (8 * i);
|
||||
}
|
||||
} else {
|
||||
zend_throw_error(random_ce_Random_BrokenRandomEngineError, "A random engine must return a non-empty string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&retval);
|
||||
|
||||
25
ext/random/tests/02_engine/user_reference_return.phpt
Normal file
25
ext/random/tests/02_engine/user_reference_return.phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
Random: Engine: User: Returning by reference works
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
use Random\Engine;
|
||||
use Random\Randomizer;
|
||||
|
||||
final class ReferenceEngine implements Engine
|
||||
{
|
||||
private $field = 'abcdef';
|
||||
|
||||
public function &generate(): string
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
}
|
||||
|
||||
$randomizer = new Randomizer(new ReferenceEngine());
|
||||
|
||||
var_dump($randomizer->getBytes(64));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(64) "abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"
|
||||
@@ -10,7 +10,8 @@ final class EmptyStringEngine implements Engine
|
||||
{
|
||||
public function generate(): string
|
||||
{
|
||||
return '';
|
||||
// Create a non-interned empty string.
|
||||
return preg_replace('/./', '', random_bytes(4));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user