Merge branch 'PHP-7.0' into PHP-7.1

This commit is contained in:
Nikita Popov 2017-07-18 22:15:20 +02:00
commit 8e7c99acf4
4 changed files with 149 additions and 54 deletions

3
NEWS
View File

@ -6,6 +6,9 @@ PHP NEWS
. Fixed bug #74892 (Url Rewriting (trans_sid) not working on urls that start . Fixed bug #74892 (Url Rewriting (trans_sid) not working on urls that start
with "#"). (Andrew Nester) with "#"). (Andrew Nester)
- SPL:
. Fixed bug #74669 (Unserialize ArrayIterator broken). (Andrew Nester)
03 Aug 2017, PHP 7.1.8 03 Aug 2017, PHP 7.1.8
- Core: - Core:

View File

@ -1740,13 +1740,14 @@ SPL_METHOD(Array, serialize)
*/ */
SPL_METHOD(Array, unserialize) SPL_METHOD(Array, unserialize)
{ {
spl_array_object *intern = Z_SPLARRAY_P(getThis()); zval *object = getThis();
spl_array_object *intern = Z_SPLARRAY_P(object);
char *buf; char *buf;
size_t buf_len; size_t buf_len;
const unsigned char *p, *s; const unsigned char *p, *s;
php_unserialize_data_t var_hash; php_unserialize_data_t var_hash;
zval *members, *zflags; zval *members, *zflags, *array;
zend_long flags; zend_long flags;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &buf, &buf_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &buf, &buf_len) == FAILURE) {
@ -1788,24 +1789,38 @@ SPL_METHOD(Array, unserialize)
} }
++p; ++p;
if (*p!='m') { if (flags & SPL_ARRAY_IS_SELF) {
if (*p!='a' && *p!='O' && *p!='C' && *p!='r') { /* If IS_SELF is used, the flags are not followed by an array/object */
goto outexcept;
}
intern->ar_flags &= ~SPL_ARRAY_CLONE_MASK; intern->ar_flags &= ~SPL_ARRAY_CLONE_MASK;
intern->ar_flags |= flags & SPL_ARRAY_CLONE_MASK; intern->ar_flags |= flags & SPL_ARRAY_CLONE_MASK;
zval_ptr_dtor(&intern->array); zval_ptr_dtor(&intern->array);
ZVAL_UNDEF(&intern->array); ZVAL_UNDEF(&intern->array);
if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash) } else {
|| (Z_TYPE(intern->array) != IS_ARRAY && Z_TYPE(intern->array) != IS_OBJECT)) { if (*p!='a' && *p!='O' && *p!='C' && *p!='r') {
goto outexcept; goto outexcept;
} }
var_push_dtor(&var_hash, &intern->array);
array = var_tmp_var(&var_hash);
if (!php_var_unserialize(array, &p, s + buf_len, &var_hash)
|| (Z_TYPE_P(array) != IS_ARRAY && Z_TYPE_P(array) != IS_OBJECT)) {
goto outexcept;
}
intern->ar_flags &= ~SPL_ARRAY_CLONE_MASK;
intern->ar_flags |= flags & SPL_ARRAY_CLONE_MASK;
if (Z_TYPE_P(array) == IS_ARRAY) {
zval_ptr_dtor(&intern->array);
ZVAL_COPY(&intern->array, array);
} else {
spl_array_set_array(object, intern, array, 0L, 1);
}
if (*p != ';') {
goto outexcept;
}
++p;
} }
if (*p != ';') {
goto outexcept;
}
++p;
/* members */ /* members */
if (*p!= 'm' || *++p != ':') { if (*p!= 'm' || *++p != ':') {

View File

@ -8,45 +8,10 @@ $data = unserialize($exploit);
var_dump($data); var_dump($data);
?> ?>
===DONE===
--EXPECTF-- --EXPECTF--
object(ArrayObject)#1 (2) { Fatal error: Uncaught InvalidArgumentException: Overloaded object of type DateInterval is not compatible with ArrayObject in %s
[0]=> Stack trace:
int(0) %s
["storage":"ArrayObject":private]=> %s
object(DateInterval)#2 (16) { %s
["y"]=> %s
int(3)
["m"]=>
int(-1)
["d"]=>
int(-1)
["h"]=>
int(-1)
["i"]=>
int(-1)
["s"]=>
int(-1)
["f"]=>
float(-1)
["weekday"]=>
int(-1)
["weekday_behavior"]=>
int(-1)
["first_last_day_of"]=>
int(-1)
["invert"]=>
int(0)
["days"]=>
int(-1)
["special_type"]=>
int(0)
["special_amount"]=>
int(-1)
["have_weekday_relative"]=>
int(0)
["have_special_relative"]=>
int(0)
}
}
===DONE===

112
ext/spl/tests/bug74669.phpt Normal file
View File

@ -0,0 +1,112 @@
--TEST--
Bug #74669: Unserialize ArrayIterator broken
--FILE--
<?php
class Container implements Iterator
{
public $container;
public $iterator;
public function __construct()
{
$this->container = new ArrayObject();
$this->iterator = $this->container->getIterator();
}
public function append($element)
{
$this->container->append($element);
}
public function current()
{
return $this->iterator->current();
}
public function next()
{
$this->iterator->next();
}
public function key()
{
return $this->iterator->key();
}
public function valid()
{
return $this->iterator->valid();
}
public function rewind()
{
$this->iterator->rewind();
}
}
class SelfArray extends ArrayObject
{
public function __construct()
{
parent::__construct($this);
}
}
$container = new Container();
$container->append('test1');
$container->append('test2');
$container->valid();
$serialized = serialize($container);
unset($container);
$container = unserialize($serialized);
foreach ($container as $key => $value) {
echo $key . ' => ' . $value . PHP_EOL;
}
$arObj = new ArrayObject(['test1', 'test2']);
$serialized = serialize($container);
unset($arObj);
$arObj = unserialize($serialized);
foreach($arObj as $key => $value) {
echo $key . ' => ' . $value . PHP_EOL;
}
$payload = 'x:i:33554432;O:8:"stdClass":0:{};m:a:0:{}';
$str = 'C:11:"ArrayObject":' . strlen($payload) . ':{' . $payload . '}';
$ao = unserialize($str);
var_dump($ao['foo']);
$selfArray = new SelfArray();
$selfArray['foo'] = 'bar';
var_dump($selfArray);
$serialized = serialize($selfArray);
var_dump($serialized);
unset($selfArray);
$selfArray = unserialize($serialized);
var_dump($selfArray);
var_dump($selfArray['foo']);
?>
--EXPECTF--
0 => test1
1 => test2
0 => test1
1 => test2
Notice: Undefined index: foo in %s on line %s
NULL
object(SelfArray)#9 (1) {
["foo"]=>
string(3) "bar"
}
string(62) "C:9:"SelfArray":41:{x:i:16777216;m:a:1:{s:3:"foo";s:3:"bar";}}"
object(SelfArray)#9 (1) {
["foo"]=>
string(3) "bar"
}
string(3) "bar"