]> granicus.if.org Git - php/commitdiff
Improved fix for #71940
authorXinchen Hui <laruence@gmail.com>
Thu, 7 Apr 2016 11:28:54 +0000 (19:28 +0800)
committerXinchen Hui <laruence@gmail.com>
Thu, 7 Apr 2016 11:28:54 +0000 (19:28 +0800)
ext/standard/var.c
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re

index bc766990703e52958974557a0bdf1f141995e9ce..ca621dd8a4d51801a29eca9f128c3fe0436b3a70 100644 (file)
@@ -1039,7 +1039,7 @@ PHP_FUNCTION(unserialize)
 
        if (!php_var_unserialize_ex(return_value, &p, p + buf_len, &var_hash, class_hash)) {
                PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-               if(class_hash) {
+               if (class_hash) {
                        zend_hash_destroy(class_hash);
                        FREE_HASHTABLE(class_hash);
                }
@@ -1050,8 +1050,12 @@ PHP_FUNCTION(unserialize)
                }
                RETURN_FALSE;
        }
+       /* We should keep an reference to return_value to prevent it from being dtor
+          in case nesting calls to unserialize */
+       var_push_dtor(&var_hash, return_value);
+
        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
-       if(class_hash) {
+       if (class_hash) {
                zend_hash_destroy(class_hash);
                FREE_HASHTABLE(class_hash);
        }
index 03ba75087377823b12130fdcd778d78c66908176..389c42b3de75c2652cd51baa6691537a22650713 100644 (file)
@@ -574,7 +574,7 @@ yy2:
        yych = *(YYMARKER = ++YYCURSOR);
        if (yych == ':') goto yy95;
 yy3:
-#line 886 "ext/standard/var_unserializer.re"
+#line 884 "ext/standard/var_unserializer.re"
        { return 0; }
 #line 580 "ext/standard/var_unserializer.c"
 yy4:
@@ -619,7 +619,7 @@ yy13:
        goto yy3;
 yy14:
        ++YYCURSOR;
-#line 880 "ext/standard/var_unserializer.re"
+#line 878 "ext/standard/var_unserializer.re"
        {
        /* this is the case where we have less data than planned */
        php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
@@ -655,7 +655,7 @@ yy20:
        yych = *++YYCURSOR;
        if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 735 "ext/standard/var_unserializer.re"
+#line 733 "ext/standard/var_unserializer.re"
        {
        size_t len, len2, len3, maxlen;
        zend_long elements;
@@ -825,7 +825,7 @@ yy27:
        yych = *++YYCURSOR;
        if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 728 "ext/standard/var_unserializer.re"
+#line 726 "ext/standard/var_unserializer.re"
        {
     if (!var_hash) return 0;
 
@@ -871,15 +871,13 @@ yy34:
                zend_hash_real_init(Z_ARRVAL_P(rval), 0);
        }
 
-       /* We should keep an reference to rval to prevent it from being dtor */
-       var_push_dtor(var_hash, rval);
        if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) {
                return 0;
        }
 
        return finish_nested_data(UNSERIALIZE_PASSTHRU);
 }
-#line 883 "ext/standard/var_unserializer.c"
+#line 881 "ext/standard/var_unserializer.c"
 yy39:
        yych = *++YYCURSOR;
        if (yych == '+') goto yy40;
@@ -934,7 +932,7 @@ yy41:
        ZVAL_STR(rval, str);
        return 1;
 }
-#line 938 "ext/standard/var_unserializer.c"
+#line 936 "ext/standard/var_unserializer.c"
 yy46:
        yych = *++YYCURSOR;
        if (yych == '+') goto yy47;
@@ -987,7 +985,7 @@ yy48:
        ZVAL_STRINGL(rval, str, len);
        return 1;
 }
-#line 991 "ext/standard/var_unserializer.c"
+#line 989 "ext/standard/var_unserializer.c"
 yy53:
        yych = *++YYCURSOR;
        if (yych <= '/') {
@@ -1084,7 +1082,7 @@ use_double:
        ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
        return 1;
 }
-#line 1088 "ext/standard/var_unserializer.c"
+#line 1086 "ext/standard/var_unserializer.c"
 yy65:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -1159,7 +1157,7 @@ yy73:
 
        return 1;
 }
-#line 1163 "ext/standard/var_unserializer.c"
+#line 1161 "ext/standard/var_unserializer.c"
 yy76:
        yych = *++YYCURSOR;
        if (yych == 'N') goto yy73;
@@ -1212,7 +1210,7 @@ yy79:
        ZVAL_LONG(rval, parse_iv(start + 2));
        return 1;
 }
-#line 1216 "ext/standard/var_unserializer.c"
+#line 1214 "ext/standard/var_unserializer.c"
 yy83:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1226,7 +1224,7 @@ yy83:
        ZVAL_BOOL(rval, parse_iv(start + 2));
        return 1;
 }
-#line 1230 "ext/standard/var_unserializer.c"
+#line 1228 "ext/standard/var_unserializer.c"
 yy87:
        ++YYCURSOR;
 #line 573 "ext/standard/var_unserializer.re"
@@ -1235,7 +1233,7 @@ yy87:
        ZVAL_NULL(rval);
        return 1;
 }
-#line 1239 "ext/standard/var_unserializer.c"
+#line 1237 "ext/standard/var_unserializer.c"
 yy89:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -1283,7 +1281,7 @@ yy91:
 
        return 1;
 }
-#line 1287 "ext/standard/var_unserializer.c"
+#line 1285 "ext/standard/var_unserializer.c"
 yy95:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -1332,9 +1330,9 @@ yy97:
 
        return 1;
 }
-#line 1336 "ext/standard/var_unserializer.c"
+#line 1334 "ext/standard/var_unserializer.c"
 }
-#line 888 "ext/standard/var_unserializer.re"
+#line 886 "ext/standard/var_unserializer.re"
 
 
        return 0;
index 02478167f021aec4079ae922edd15db8291fcd0e..c7e058163031dbf500889e1bbc76ba96169784ae 100644 (file)
@@ -716,8 +716,6 @@ use_double:
                zend_hash_real_init(Z_ARRVAL_P(rval), 0);
        }
 
-       /* We should keep an reference to rval to prevent it from being dtor */
-       var_push_dtor(var_hash, rval);
        if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) {
                return 0;
        }