]> granicus.if.org Git - php/commitdiff
Avoid visibility checks for classes without predefined properties
authorDmitry Stogov <dmitry@zend.com>
Thu, 30 Nov 2017 10:13:42 +0000 (13:13 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 30 Nov 2017 10:13:42 +0000 (13:13 +0300)
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re

index 42be1898745d7dc7f7e8f4727d078b840a0591fc..ceafd502054ecde8c946146c12bcde047ab6f2af 100644 (file)
@@ -436,60 +436,61 @@ numeric_key:
                } else {
                        if (EXPECTED(Z_TYPE(key) == IS_STRING)) {
 string_key:
-                               {
+                               if (Z_TYPE_P(rval) == IS_OBJECT
+                                               && zend_hash_num_elements(&Z_OBJCE_P(rval)->properties_info) > 0) {
                                        zend_property_info *existing_propinfo;
                                        zend_string *new_key;
                                        const char *unmangled_class = NULL; 
                                        const char *unmangled_prop;
                                        size_t unmangled_prop_len;
+                                       zend_string *unmangled;
 
                                        if (UNEXPECTED(zend_unmangle_property_name_ex(Z_STR(key), &unmangled_class, &unmangled_prop, &unmangled_prop_len) == FAILURE)) {
                                                zval_ptr_dtor(&key);
                                                return 0;
                                        }
 
-                                       if (Z_TYPE_P(rval) == IS_OBJECT) {
-                                               zend_string *unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
+                                       unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
 
-                                               if (((existing_propinfo = zend_hash_find_ptr(&Z_OBJCE_P(rval)->properties_info, unmangled)) != NULL) 
-                                                               && (existing_propinfo->flags & ZEND_ACC_PPP_MASK)) {
-                                                       if (existing_propinfo->flags & ZEND_ACC_PROTECTED) {
+                                       existing_propinfo = zend_hash_find_ptr(&Z_OBJCE_P(rval)->properties_info, unmangled);
+                                       if ((existing_propinfo != NULL) 
+                                                       && (existing_propinfo->flags & ZEND_ACC_PPP_MASK)) {
+                                               if (existing_propinfo->flags & ZEND_ACC_PROTECTED) {
+                                                       new_key = zend_mangle_property_name(
+                                                               "*", 1, ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), 0);
+                                                       zend_string_release(unmangled);
+                                               } else if (existing_propinfo->flags & ZEND_ACC_PRIVATE) {
+                                                       if (unmangled_class != NULL && strcmp(unmangled_class, "*") != 0) {
                                                                new_key = zend_mangle_property_name(
-                                                                       "*", 1, ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), 0);
-                                                               zend_string_release(unmangled);
-                                                       } else if (existing_propinfo->flags & ZEND_ACC_PRIVATE) {
-                                                               if (unmangled_class != NULL && strcmp(unmangled_class, "*") != 0) {
-                                                                       new_key = zend_mangle_property_name(
-                                                                               unmangled_class, strlen(unmangled_class),
-                                                                               ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
-                                                                               0);
-                                                               } else {
-                                                                       new_key = zend_mangle_property_name(
-                                                                               ZSTR_VAL(existing_propinfo->ce->name), ZSTR_LEN(existing_propinfo->ce->name),
+                                                                       unmangled_class, strlen(unmangled_class),
                                                                                ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
                                                                                0);
-                                                               }
-                                                               zend_string_release(unmangled);
                                                        } else {
-                                                               ZEND_ASSERT(existing_propinfo->flags & ZEND_ACC_PUBLIC);
-                                                               new_key = unmangled;
+                                                               new_key = zend_mangle_property_name(
+                                                                       ZSTR_VAL(existing_propinfo->ce->name), ZSTR_LEN(existing_propinfo->ce->name),
+                                                                       ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
+                                                                       0);
                                                        }
-                                                       zend_string_release(Z_STR(key));
-                                                       ZVAL_STR(&key, new_key);
-                                               } else {
                                                        zend_string_release(unmangled);
+                                               } else {
+                                                       ZEND_ASSERT(existing_propinfo->flags & ZEND_ACC_PUBLIC);
+                                                       new_key = unmangled;
                                                }
+                                               zend_string_release(Z_STR(key));
+                                               ZVAL_STR(&key, new_key);
+                                       } else {
+                                               zend_string_release(unmangled);
                                        }
+                               }
 
-                                       if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) {
-                                               if (Z_TYPE_P(old_data) == IS_INDIRECT) {
-                                                       old_data = Z_INDIRECT_P(old_data);
-                                               }
-                                               var_push_dtor(var_hash, old_data);
-                                               data = zend_hash_update_ind(ht, Z_STR(key), &d);
-                                       } else {
-                                               data = zend_hash_add_new(ht, Z_STR(key), &d);
+                               if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) {
+                                       if (Z_TYPE_P(old_data) == IS_INDIRECT) {
+                                               old_data = Z_INDIRECT_P(old_data);
                                        }
+                                       var_push_dtor(var_hash, old_data);
+                                       data = zend_hash_update_ind(ht, Z_STR(key), &d);
+                               } else {
+                                       data = zend_hash_add_new(ht, Z_STR(key), &d);
                                }
                        } else if (Z_TYPE(key) == IS_LONG) {
                                /* object properties should include no integers */
@@ -667,7 +668,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER, int as_key)
        start = cursor;
 
 
-#line 671 "ext/standard/var_unserializer.c"
+#line 672 "ext/standard/var_unserializer.c"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -725,9 +726,9 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER, int as_key)
 yy2:
        ++YYCURSOR;
 yy3:
-#line 1070 "ext/standard/var_unserializer.re"
+#line 1071 "ext/standard/var_unserializer.re"
        { return 0; }
-#line 731 "ext/standard/var_unserializer.c"
+#line 732 "ext/standard/var_unserializer.c"
 yy4:
        yych = *(YYMARKER = ++YYCURSOR);
        if (yych == ':') goto yy17;
@@ -774,13 +775,13 @@ yy14:
        goto yy3;
 yy15:
        ++YYCURSOR;
-#line 1064 "ext/standard/var_unserializer.re"
+#line 1065 "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");
        return 0; /* not sure if it should be 0 or 1 here? */
 }
-#line 784 "ext/standard/var_unserializer.c"
+#line 785 "ext/standard/var_unserializer.c"
 yy17:
        yych = *++YYCURSOR;
        if (yybm[0+yych] & 128) {
@@ -791,13 +792,13 @@ yy18:
        goto yy3;
 yy19:
        ++YYCURSOR;
-#line 725 "ext/standard/var_unserializer.re"
+#line 726 "ext/standard/var_unserializer.re"
        {
        *p = YYCURSOR;
        ZVAL_NULL(rval);
        return 1;
 }
-#line 801 "ext/standard/var_unserializer.c"
+#line 802 "ext/standard/var_unserializer.c"
 yy21:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1001,7 +1002,7 @@ yy56:
        goto yy18;
 yy57:
        ++YYCURSOR;
-#line 675 "ext/standard/var_unserializer.re"
+#line 676 "ext/standard/var_unserializer.re"
        {
        zend_long id;
 
@@ -1026,7 +1027,7 @@ yy57:
 
        return 1;
 }
-#line 1030 "ext/standard/var_unserializer.c"
+#line 1031 "ext/standard/var_unserializer.c"
 yy59:
        yych = *++YYCURSOR;
        if (yych == '"') goto yy80;
@@ -1037,22 +1038,22 @@ yy60:
        goto yy18;
 yy61:
        ++YYCURSOR;
-#line 731 "ext/standard/var_unserializer.re"
+#line 732 "ext/standard/var_unserializer.re"
        {
        *p = YYCURSOR;
        ZVAL_FALSE(rval);
        return 1;
 }
-#line 1047 "ext/standard/var_unserializer.c"
+#line 1048 "ext/standard/var_unserializer.c"
 yy63:
        ++YYCURSOR;
-#line 737 "ext/standard/var_unserializer.re"
+#line 738 "ext/standard/var_unserializer.re"
        {
        *p = YYCURSOR;
        ZVAL_TRUE(rval);
        return 1;
 }
-#line 1056 "ext/standard/var_unserializer.c"
+#line 1057 "ext/standard/var_unserializer.c"
 yy65:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
@@ -1072,7 +1073,7 @@ yy65:
        }
 yy67:
        ++YYCURSOR;
-#line 785 "ext/standard/var_unserializer.re"
+#line 786 "ext/standard/var_unserializer.re"
        {
 #if SIZEOF_ZEND_LONG == 4
 use_double:
@@ -1081,7 +1082,7 @@ use_double:
        ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
        return 1;
 }
-#line 1085 "ext/standard/var_unserializer.c"
+#line 1086 "ext/standard/var_unserializer.c"
 yy69:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -1103,7 +1104,7 @@ yy71:
        goto yy18;
 yy72:
        ++YYCURSOR;
-#line 743 "ext/standard/var_unserializer.re"
+#line 744 "ext/standard/var_unserializer.re"
        {
 #if SIZEOF_ZEND_LONG == 4
        int digits = YYCURSOR - start - 3;
@@ -1129,14 +1130,14 @@ yy72:
        ZVAL_LONG(rval, parse_iv(start + 2));
        return 1;
 }
-#line 1133 "ext/standard/var_unserializer.c"
+#line 1134 "ext/standard/var_unserializer.c"
 yy74:
        yych = *++YYCURSOR;
        if (yych == '"') goto yy88;
        goto yy18;
 yy75:
        ++YYCURSOR;
-#line 700 "ext/standard/var_unserializer.re"
+#line 701 "ext/standard/var_unserializer.re"
        {
        zend_long id;
 
@@ -1161,14 +1162,14 @@ yy75:
 
        return 1;
 }
-#line 1165 "ext/standard/var_unserializer.c"
+#line 1166 "ext/standard/var_unserializer.c"
 yy77:
        yych = *++YYCURSOR;
        if (yych == '"') goto yy90;
        goto yy18;
 yy78:
        ++YYCURSOR;
-#line 912 "ext/standard/var_unserializer.re"
+#line 913 "ext/standard/var_unserializer.re"
        {
        size_t len, len2, len3, maxlen;
        zend_long elements;
@@ -1320,10 +1321,10 @@ yy78:
 
        return object_common2(UNSERIALIZE_PASSTHRU, elements);
 }
-#line 1324 "ext/standard/var_unserializer.c"
+#line 1325 "ext/standard/var_unserializer.c"
 yy80:
        ++YYCURSOR;
-#line 834 "ext/standard/var_unserializer.re"
+#line 835 "ext/standard/var_unserializer.re"
        {
        size_t len, maxlen;
        zend_string *str;
@@ -1357,10 +1358,10 @@ yy80:
        ZVAL_STR(rval, str);
        return 1;
 }
-#line 1361 "ext/standard/var_unserializer.c"
+#line 1362 "ext/standard/var_unserializer.c"
 yy82:
        ++YYCURSOR;
-#line 868 "ext/standard/var_unserializer.re"
+#line 869 "ext/standard/var_unserializer.re"
        {
        zend_long elements = parse_iv(start + 2);
        /* use iv() not uiv() in order to check data range */
@@ -1393,7 +1394,7 @@ yy82:
 
        return finish_nested_data(UNSERIALIZE_PASSTHRU);
 }
-#line 1397 "ext/standard/var_unserializer.c"
+#line 1398 "ext/standard/var_unserializer.c"
 yy84:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1412,7 +1413,7 @@ yy87:
        goto yy18;
 yy88:
        ++YYCURSOR;
-#line 901 "ext/standard/var_unserializer.re"
+#line 902 "ext/standard/var_unserializer.re"
        {
        zend_long elements;
     if (!var_hash) return 0;
@@ -1423,10 +1424,10 @@ yy88:
        }
        return object_common2(UNSERIALIZE_PASSTHRU, elements);
 }
-#line 1427 "ext/standard/var_unserializer.c"
+#line 1428 "ext/standard/var_unserializer.c"
 yy90:
        ++YYCURSOR;
-#line 794 "ext/standard/var_unserializer.re"
+#line 795 "ext/standard/var_unserializer.re"
        {
        size_t len, maxlen;
        char *str;
@@ -1466,10 +1467,10 @@ yy90:
        }
        return 1;
 }
-#line 1470 "ext/standard/var_unserializer.c"
+#line 1471 "ext/standard/var_unserializer.c"
 yy92:
        ++YYCURSOR;
-#line 769 "ext/standard/var_unserializer.re"
+#line 770 "ext/standard/var_unserializer.re"
        {
        *p = YYCURSOR;
 
@@ -1485,9 +1486,9 @@ yy92:
 
        return 1;
 }
-#line 1489 "ext/standard/var_unserializer.c"
+#line 1490 "ext/standard/var_unserializer.c"
 }
-#line 1072 "ext/standard/var_unserializer.re"
+#line 1073 "ext/standard/var_unserializer.re"
 
 
        return 0;
index 6c9c36fec0502705cf0d25239ef1c21acb2ad1dd..67348af0ba805b0f6f917da953041b3d768f2820 100644 (file)
@@ -440,60 +440,61 @@ numeric_key:
                } else {
                        if (EXPECTED(Z_TYPE(key) == IS_STRING)) {
 string_key:
-                               {
+                               if (Z_TYPE_P(rval) == IS_OBJECT
+                                               && zend_hash_num_elements(&Z_OBJCE_P(rval)->properties_info) > 0) {
                                        zend_property_info *existing_propinfo;
                                        zend_string *new_key;
                                        const char *unmangled_class = NULL; 
                                        const char *unmangled_prop;
                                        size_t unmangled_prop_len;
+                                       zend_string *unmangled;
 
                                        if (UNEXPECTED(zend_unmangle_property_name_ex(Z_STR(key), &unmangled_class, &unmangled_prop, &unmangled_prop_len) == FAILURE)) {
                                                zval_ptr_dtor(&key);
                                                return 0;
                                        }
 
-                                       if (Z_TYPE_P(rval) == IS_OBJECT) {
-                                               zend_string *unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
+                                       unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
 
-                                               if (((existing_propinfo = zend_hash_find_ptr(&Z_OBJCE_P(rval)->properties_info, unmangled)) != NULL) 
-                                                               && (existing_propinfo->flags & ZEND_ACC_PPP_MASK)) {
-                                                       if (existing_propinfo->flags & ZEND_ACC_PROTECTED) {
+                                       existing_propinfo = zend_hash_find_ptr(&Z_OBJCE_P(rval)->properties_info, unmangled);
+                                       if ((existing_propinfo != NULL) 
+                                                       && (existing_propinfo->flags & ZEND_ACC_PPP_MASK)) {
+                                               if (existing_propinfo->flags & ZEND_ACC_PROTECTED) {
+                                                       new_key = zend_mangle_property_name(
+                                                               "*", 1, ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), 0);
+                                                       zend_string_release(unmangled);
+                                               } else if (existing_propinfo->flags & ZEND_ACC_PRIVATE) {
+                                                       if (unmangled_class != NULL && strcmp(unmangled_class, "*") != 0) {
                                                                new_key = zend_mangle_property_name(
-                                                                       "*", 1, ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), 0);
-                                                               zend_string_release(unmangled);
-                                                       } else if (existing_propinfo->flags & ZEND_ACC_PRIVATE) {
-                                                               if (unmangled_class != NULL && strcmp(unmangled_class, "*") != 0) {
-                                                                       new_key = zend_mangle_property_name(
-                                                                               unmangled_class, strlen(unmangled_class),
-                                                                               ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
-                                                                               0);
-                                                               } else {
-                                                                       new_key = zend_mangle_property_name(
-                                                                               ZSTR_VAL(existing_propinfo->ce->name), ZSTR_LEN(existing_propinfo->ce->name),
+                                                                       unmangled_class, strlen(unmangled_class),
                                                                                ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
                                                                                0);
-                                                               }
-                                                               zend_string_release(unmangled);
                                                        } else {
-                                                               ZEND_ASSERT(existing_propinfo->flags & ZEND_ACC_PUBLIC);
-                                                               new_key = unmangled;
+                                                               new_key = zend_mangle_property_name(
+                                                                       ZSTR_VAL(existing_propinfo->ce->name), ZSTR_LEN(existing_propinfo->ce->name),
+                                                                       ZSTR_VAL(unmangled), ZSTR_LEN(unmangled),
+                                                                       0);
                                                        }
-                                                       zend_string_release(Z_STR(key));
-                                                       ZVAL_STR(&key, new_key);
-                                               } else {
                                                        zend_string_release(unmangled);
+                                               } else {
+                                                       ZEND_ASSERT(existing_propinfo->flags & ZEND_ACC_PUBLIC);
+                                                       new_key = unmangled;
                                                }
+                                               zend_string_release(Z_STR(key));
+                                               ZVAL_STR(&key, new_key);
+                                       } else {
+                                               zend_string_release(unmangled);
                                        }
+                               }
 
-                                       if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) {
-                                               if (Z_TYPE_P(old_data) == IS_INDIRECT) {
-                                                       old_data = Z_INDIRECT_P(old_data);
-                                               }
-                                               var_push_dtor(var_hash, old_data);
-                                               data = zend_hash_update_ind(ht, Z_STR(key), &d);
-                                       } else {
-                                               data = zend_hash_add_new(ht, Z_STR(key), &d);
+                               if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) {
+                                       if (Z_TYPE_P(old_data) == IS_INDIRECT) {
+                                               old_data = Z_INDIRECT_P(old_data);
                                        }
+                                       var_push_dtor(var_hash, old_data);
+                                       data = zend_hash_update_ind(ht, Z_STR(key), &d);
+                               } else {
+                                       data = zend_hash_add_new(ht, Z_STR(key), &d);
                                }
                        } else if (Z_TYPE(key) == IS_LONG) {
                                /* object properties should include no integers */