@@ -1065,7 +1065,7 @@ PHP_FUNCTION(unserialize)
1065
1065
const unsigned char * p ;
1066
1066
php_unserialize_data_t var_hash ;
1067
1067
zval * options = NULL , * classes = NULL ;
1068
- HashTable * class_hash = NULL ;
1068
+ HashTable * class_hash = NULL , * prev_class_hash ;
1069
1069
1070
1070
if (zend_parse_parameters (ZEND_NUM_ARGS (), "s|a" , & buf , & buf_len , & options ) == FAILURE ) {
1071
1071
RETURN_FALSE ;
@@ -1077,7 +1077,9 @@ PHP_FUNCTION(unserialize)
1077
1077
1078
1078
p = (const unsigned char * ) buf ;
1079
1079
PHP_VAR_UNSERIALIZE_INIT (var_hash );
1080
- if (options != NULL ) {
1080
+
1081
+ prev_class_hash = php_var_unserialize_get_allowed_classes (var_hash );
1082
+ if (options != NULL ) {
1081
1083
classes = zend_hash_str_find (Z_ARRVAL_P (options ), "allowed_classes" , sizeof ("allowed_classes" )- 1 );
1082
1084
if (classes && Z_TYPE_P (classes ) != IS_ARRAY && Z_TYPE_P (classes ) != IS_TRUE && Z_TYPE_P (classes ) != IS_FALSE ) {
1083
1085
php_error_docref (NULL , E_WARNING , "allowed_classes option should be array or boolean" );
@@ -1104,32 +1106,31 @@ PHP_FUNCTION(unserialize)
1104
1106
}
1105
1107
1106
1108
if (!php_var_unserialize (return_value , & p , p + buf_len , & var_hash )) {
1107
- PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
1108
- if (class_hash ) {
1109
- zend_hash_destroy (class_hash );
1110
- FREE_HASHTABLE (class_hash );
1111
- }
1112
1109
zval_ptr_dtor (return_value );
1113
1110
if (!EG (exception )) {
1114
1111
php_error_docref (NULL , E_NOTICE , "Error at offset " ZEND_LONG_FMT " of %zd bytes" ,
1115
1112
(zend_long )((char * )p - buf ), buf_len );
1116
1113
}
1117
- RETURN_FALSE ;
1118
- }
1119
- /* We should keep an reference to return_value to prevent it from being dtor
1120
- in case nesting calls to unserialize */
1121
- var_push_dtor (& var_hash , return_value );
1114
+ RETVAL_FALSE ;
1115
+ } else {
1116
+ /* We should keep an reference to return_value to prevent it from being dtor
1117
+ in case nesting calls to unserialize */
1118
+ var_push_dtor (& var_hash , return_value );
1122
1119
1123
- /* Ensure return value is a value */
1124
- if (Z_ISREF_P (return_value )) {
1125
- zend_unwrap_reference (return_value );
1120
+ /* Ensure return value is a value */
1121
+ if (Z_ISREF_P (return_value )) {
1122
+ zend_unwrap_reference (return_value );
1123
+ }
1126
1124
}
1127
1125
1128
- PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
1129
1126
if (class_hash ) {
1130
1127
zend_hash_destroy (class_hash );
1131
1128
FREE_HASHTABLE (class_hash );
1132
1129
}
1130
+
1131
+ /* Reset to previous allowed_classes in case this is a nested call */
1132
+ php_var_unserialize_set_allowed_classes (var_hash , prev_class_hash );
1133
+ PHP_VAR_UNSERIALIZE_DESTROY (var_hash );
1133
1134
}
1134
1135
/* }}} */
1135
1136
0 commit comments