Fix bug #73029 - Missing type check when unserializing SplArray
authorStanislav Malyshev <stas@php.net>
Mon, 12 Sep 2016 03:24:13 +0000 (20:24 -0700)
committerStanislav Malyshev <stas@php.net>
Tue, 13 Sep 2016 04:04:23 +0000 (21:04 -0700)
ext/spl/spl_array.c
ext/spl/tests/bug73029.phpt [new file with mode: 0644]

index 42a8e7aa44986943b73e94da93d02737532a9b04..700d6093dd51ddb1c46b290d13330eafb5a2fc90 100644 (file)
@@ -308,7 +308,7 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
        long index;
        HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
 
-       if (!offset) {
+       if (!offset || !ht) {
                return &EG(uninitialized_zval_ptr);
        }
 
@@ -626,7 +626,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o
                HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
 
                switch(Z_TYPE_P(offset)) {
-                       case IS_STRING: 
+                       case IS_STRING:
                                if (zend_symtable_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &tmp) != FAILURE) {
                                        if (check_empty == 2) {
                                                return 1;
@@ -638,7 +638,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o
 
                        case IS_DOUBLE:
                        case IS_RESOURCE:
-                       case IS_BOOL: 
+                       case IS_BOOL:
                        case IS_LONG:
                                if (offset->type == IS_DOUBLE) {
                                        index = (long)Z_DVAL_P(offset);
@@ -1810,7 +1810,9 @@ SPL_METHOD(Array, unserialize)
                intern->ar_flags |= flags & SPL_ARRAY_CLONE_MASK;
                zval_ptr_dtor(&intern->array);
                ALLOC_INIT_ZVAL(intern->array);
-               if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) {
+               if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)
+                               || (Z_TYPE_P(intern->array) != IS_ARRAY && Z_TYPE_P(intern->array) != IS_OBJECT)) {
+                       zval_ptr_dtor(&intern->array);
                        goto outexcept;
                }
                var_push_dtor(&var_hash, &intern->array);
diff --git a/ext/spl/tests/bug73029.phpt b/ext/spl/tests/bug73029.phpt
new file mode 100644 (file)
index 0000000..a379f80
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Bug #73029: Missing type check when unserializing SplArray
+--FILE--
+<?php
+try {
+$a = 'C:11:"ArrayObject":19:0x:i:0;r:2;;m:a:0:{}}';
+$m = unserialize($a);
+$x = $m[2];
+} catch(UnexpectedValueException $e) {
+       print $e->getMessage() . "\n";
+}
+?>
+DONE
+--EXPECTF--
+Error at offset 10 of 19 bytes
+DONE