summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2014-07-02 17:58:11 +0800
committerXinchen Hui <laruence@php.net>2014-07-02 17:58:11 +0800
commitf48f31153364108543d9f82798ce1383176592f3 (patch)
treecbde28b1a74722ea678d9bf1dce836bc3d8fc935
parent9e2d08923f3563a6f87482b7dba472ef1c4aa1fc (diff)
parent22882a9d89712ff2b6ebc20a689a89452bba4dcd (diff)
downloadphp-git-f48f31153364108543d9f82798ce1383176592f3.tar.gz
Merge branch 'PHP-5.5' into PHP-5.6
-rw-r--r--ext/spl/spl_array.c7
-rw-r--r--ext/spl/spl_dllist.c7
-rw-r--r--ext/spl/tests/bug67538.phpt17
-rw-r--r--ext/spl/tests/bug67539.phpt15
4 files changed, 44 insertions, 2 deletions
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 32cdfe6fb4..9c49d91ca2 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -1742,6 +1742,7 @@ SPL_METHOD(Array, unserialize)
const unsigned char *p, *s;
php_unserialize_data_t var_hash;
zval *pmembers, *pflags = NULL;
+ HashTable *aht;
long flags;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) {
@@ -1752,6 +1753,12 @@ SPL_METHOD(Array, unserialize)
return;
}
+ aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
+ if (aht->nApplyCount > 0) {
+ zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
+ return;
+ }
+
/* storage */
s = p = (const unsigned char*)buf;
PHP_VAR_UNSERIALIZE_INIT(var_hash);
diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c
index fb88f58908..c48736ec6c 100644
--- a/ext/spl/spl_dllist.c
+++ b/ext/spl/spl_dllist.c
@@ -43,12 +43,10 @@ PHPAPI zend_class_entry *spl_ce_SplStack;
#define SPL_LLIST_DELREF(elem) if(!--(elem)->rc) { \
efree(elem); \
- elem = NULL; \
}
#define SPL_LLIST_CHECK_DELREF(elem) if((elem) && !--(elem)->rc) { \
efree(elem); \
- elem = NULL; \
}
#define SPL_LLIST_ADDREF(elem) (elem)->rc++
@@ -916,6 +914,11 @@ SPL_METHOD(SplDoublyLinkedList, offsetUnset)
llist->dtor(element TSRMLS_CC);
}
+ if (intern->traverse_pointer == element) {
+ SPL_LLIST_DELREF(element);
+ intern->traverse_pointer = NULL;
+ }
+
zval_ptr_dtor((zval **)&element->data);
element->data = NULL;
diff --git a/ext/spl/tests/bug67538.phpt b/ext/spl/tests/bug67538.phpt
new file mode 100644
index 0000000000..b6f3848c36
--- /dev/null
+++ b/ext/spl/tests/bug67538.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #67538 (SPL Iterators use-after-free)
+--FILE--
+<?php
+$list = new SplDoublyLinkedList();
+$list->push('a');
+$list->push('b');
+
+$list->rewind();
+$list->offsetUnset(0);
+$list->push('b');
+$list->offsetUnset(0);
+$list->next();
+echo "okey";
+?>
+--EXPECTF--
+okey
diff --git a/ext/spl/tests/bug67539.phpt b/ext/spl/tests/bug67539.phpt
new file mode 100644
index 0000000000..8bab2a8c21
--- /dev/null
+++ b/ext/spl/tests/bug67539.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #67539 (ArrayIterator use-after-free due to object change during sorting)
+--FILE--
+<?php
+
+$it = new ArrayIterator(array_fill(0,2,'X'), 1 );
+
+function badsort($a, $b) {
+ $GLOBALS['it']->unserialize($GLOBALS['it']->serialize());
+ return TRUE;
+}
+
+$it->uksort('badsort');
+--EXPECTF--
+Warning: Modification of ArrayObject during sorting is prohibited in %sbug67539.php on line %d