]> granicus.if.org Git - php/commitdiff
Fix couple of nasty serializer bugs:
authorStanislav Malyshev <stas@php.net>
Sun, 28 Apr 2002 16:56:33 +0000 (16:56 +0000)
committerStanislav Malyshev <stas@php.net>
Sun, 28 Apr 2002 16:56:33 +0000 (16:56 +0000)
a) When array unserializer encounters less data than it expects (like:
a:1:{}) it crashes. I don't understand exactly why it does, but the fact
is it does. So now it should catch "}" and bail out.
b) When array/object data are serialized, the count is written by hash
count. However, it can be that in-loop check fails and less data than
expected will then be written into the array. Which, due to a), would
crash on unserialize. So now it will write empty entries in place of
entries it cannot serialize (the other choice would be make two passes on
the data, which I don't like).

ext/standard/var.c
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re

index 4b8e661aae6922d8af7fc63a7cfe15efc6c95bbc..0f88fae366ccb1ea8c984026c4309e72780fe7db 100644 (file)
@@ -466,6 +466,9 @@ static void php_var_serialize_class(smart_str *buf, zval **struc, zval *retval_p
                                php_error(E_NOTICE, "__sleep should return an array only "
                                                "containing the names of instance-variables to "
                                                "serialize.");
+                               /* we should still add element even if it's not OK,
+                                  since we already wrote the length of the array before */
+                               smart_str_appendl(buf,"s:0:\"\";N;", 9);
                                continue;
                        }
 
@@ -579,12 +582,6 @@ static void php_var_serialize_intern(smart_str *buf, zval **struc, HashTable *va
                                        if (i == HASH_KEY_NON_EXISTANT)
                                                break;
                                        
-                                       if (zend_hash_get_current_data_ex(myht, 
-                                                               (void **) &data, &pos) != SUCCESS 
-                                                       || !data 
-                                                       || data == struc)
-                                               continue;
-
                                        switch (i) {
                                          case HASH_KEY_IS_LONG:
                                                        php_var_serialize_long(buf, index);
@@ -593,7 +590,17 @@ static void php_var_serialize_intern(smart_str *buf, zval **struc, HashTable *va
                                                        php_var_serialize_string(buf, key, key_len - 1);
                                                        break;
                                        }
-                                       php_var_serialize_intern(buf, data, var_hash TSRMLS_CC);
+
+                                       /* we should still add element even if it's not OK,
+                                          since we already wrote the length of the array before */
+                                       if (zend_hash_get_current_data_ex(myht, 
+                                               (void **) &data, &pos) != SUCCESS 
+                                               || !data 
+                                               || data == struc) {
+                                               smart_str_appendl(buf, "N;", 2);
+                                       } else {
+                                               php_var_serialize_intern(buf, data, var_hash TSRMLS_CC);
+                                       }
                                }
                        }
                        smart_str_appendc(buf, '}');
index eec27d0f8255cd273d80f1ad0b2b0d468dc0822e..bf0478d85dd26fc6c348e121dd5d1f61d1f7e5a6 100644 (file)
@@ -1,5 +1,5 @@
-/* Generated by re2c 0.5 on Tue Nov 27 00:35:25 2001 */
-#line 1 "/usr/src/web/php/php4/ext/standard/var_unserializer.re"
+/* Generated by re2c 0.5 on Sun Apr 28 19:47:31 2002 */
+#line 1 "var_unserializer.re"
 #include "php.h"
 #include "ext/standard/php_var.h"
 #include "php_incomplete_class.h"
@@ -272,34 +272,42 @@ yy1:      ++YYCURSOR;
 yy0:
        if((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
        yych = *YYCURSOR;
-       if(yych <= 'c'){
-               if(yych <= 'Q'){
-                       if(yych <= 'M') goto yy13;
-                       if(yych <= 'N') goto yy5;
-                       if(yych <= 'O') goto yy12;
-                       goto yy13;
+       if(yych <= 'd'){
+               if(yych <= 'R'){
+                       if(yych <= 'N'){
+                               if(yych <= 'M') goto yy15;
+                               goto yy5;
+                       } else {
+                               if(yych <= 'O') goto yy12;
+                               if(yych <= 'Q') goto yy15;
+                               goto yy3;
+                       }
                } else {
-                       if(yych <= '`'){
-                               if(yych <= 'R') goto yy3;
-                               goto yy13;
+                       if(yych <= 'a'){
+                               if(yych <= '`') goto yy15;
+                               goto yy10;
                        } else {
-                               if(yych <= 'a') goto yy10;
                                if(yych <= 'b') goto yy6;
-                               goto yy13;
+                               if(yych <= 'c') goto yy15;
+                               goto yy8;
                        }
                }
        } else {
-               if(yych <= 'n'){
-                       if(yych <= 'd') goto yy8;
-                       if(yych == 'i') goto yy7;
-                       goto yy13;
-               } else {
-                       if(yych <= 'r'){
-                               if(yych <= 'o') goto yy11;
-                               goto yy13;
+               if(yych <= 'r'){
+                       if(yych <= 'i'){
+                               if(yych <= 'h') goto yy15;
+                               goto yy7;
                        } else {
+                               if(yych == 'o') goto yy11;
+                               goto yy15;
+                       }
+               } else {
+                       if(yych <= '|'){
                                if(yych <= 's') goto yy9;
-                               if(yych <= '\277')      goto yy13;
+                               goto yy15;
+                       } else {
+                               if(yych <= '}') goto yy13;
+                               if(yych <= '\277')      goto yy15;
                        }
                }
        }
@@ -309,60 +317,68 @@ yy2:      YYCURSOR = YYMARKER;
        }
 yy3:   yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if(yych == ':') goto yy73;
+       if(yych == ':') goto yy75;
 yy4:
-#line 397
+#line 404
        { return 0; }
 yy5:   yych = *++YYCURSOR;
-       if(yych == ';') goto yy71;
+       if(yych == ';') goto yy73;
        goto yy4;
 yy6:   yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if(yych == ':') goto yy65;
+       if(yych == ':') goto yy67;
        goto yy4;
 yy7:   yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if(yych == ':') goto yy59;
+       if(yych == ':') goto yy61;
        goto yy4;
 yy8:   yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if(yych == ':') goto yy42;
+       if(yych == ':') goto yy44;
        goto yy4;
 yy9:   yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if(yych == ':') goto yy35;
+       if(yych == ':') goto yy37;
        goto yy4;
 yy10:  yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if(yych == ':') goto yy28;
+       if(yych == ':') goto yy30;
        goto yy4;
 yy11:  yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if(yych == ':') goto yy21;
+       if(yych == ':') goto yy23;
        goto yy4;
 yy12:  yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
-       if(yych == ':') goto yy14;
+       if(yych == ':') goto yy16;
        goto yy4;
 yy13:  yych = *++YYCURSOR;
+yy14:
+#line 398
+       {
+       /* this is the case where we have less data than planned */
+       zend_error(E_NOTICE, "Unexpected end of serialized data");
+       return 0; /* not sure if it should be 0 or 1 here? */
+}
+yy15:  yych = *++YYCURSOR;
        goto yy4;
-yy14:  yych = *++YYCURSOR;
-       if(yybm[0+yych] & 128)  goto yy16;
-       if(yych == '+') goto yy15;
+yy16:  yych = *++YYCURSOR;
+       if(yybm[0+yych] & 128)  goto yy18;
+       if(yych == '+') goto yy17;
        if(yych != '-') goto yy2;
-yy15:  yych = *++YYCURSOR;
-       if(yybm[0+yych] & 128)  goto yy16;
+yy17:  yych = *++YYCURSOR;
+       if(yybm[0+yych] & 128)  goto yy18;
        goto yy2;
-yy16:  ++YYCURSOR;
+yy18:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy17:  if(yybm[0+yych] & 128)  goto yy16;
+yy19:  if(yybm[0+yych] & 128)  goto yy18;
        if(yych != ':') goto yy2;
-yy18:  yych = *++YYCURSOR;
+yy20:  yych = *++YYCURSOR;
        if(yych != '"') goto yy2;
-yy19:  yych = *++YYCURSOR;
-yy20:
-#line 329
+yy21:  yych = *++YYCURSOR;
+yy22:
+#line 330
        {
        int len;
        int elements;
@@ -419,7 +435,7 @@ yy20:
                }
        } else 
                efree(class_name);
-               
+
        *p = YYCURSOR;
        elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
 
@@ -430,29 +446,29 @@ yy20:
 
        return object_common2(UNSERIALIZE_PASSTHRU, elements);
 }
-yy21:  yych = *++YYCURSOR;
+yy23:  yych = *++YYCURSOR;
        if(yych <= ','){
                if(yych != '+') goto yy2;
        } else {
-               if(yych <= '-') goto yy22;
+               if(yych <= '-') goto yy24;
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy23;
+               if(yych <= '9') goto yy25;
                goto yy2;
        }
-yy22:  yych = *++YYCURSOR;
+yy24:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy23:  ++YYCURSOR;
+yy25:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy24:  if(yych <= '/') goto yy2;
-       if(yych <= '9') goto yy23;
+yy26:  if(yych <= '/') goto yy2;
+       if(yych <= '9') goto yy25;
        if(yych >= ';') goto yy2;
-yy25:  yych = *++YYCURSOR;
+yy27:  yych = *++YYCURSOR;
        if(yych != '"') goto yy2;
-yy26:  yych = *++YYCURSOR;
-yy27:
-#line 321
+yy28:  yych = *++YYCURSOR;
+yy29:
+#line 322
        {
 
        INIT_PZVAL(*rval);
@@ -460,29 +476,29 @@ yy27:
        return object_common2(UNSERIALIZE_PASSTHRU,
                        object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
 }
-yy28:  yych = *++YYCURSOR;
+yy30:  yych = *++YYCURSOR;
        if(yych <= ','){
                if(yych != '+') goto yy2;
        } else {
-               if(yych <= '-') goto yy29;
+               if(yych <= '-') goto yy31;
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy30;
+               if(yych <= '9') goto yy32;
                goto yy2;
        }
-yy29:  yych = *++YYCURSOR;
+yy31:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy30:  ++YYCURSOR;
+yy32:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy31:  if(yych <= '/') goto yy2;
-       if(yych <= '9') goto yy30;
+yy33:  if(yych <= '/') goto yy2;
+       if(yych <= '9') goto yy32;
        if(yych >= ';') goto yy2;
-yy32:  yych = *++YYCURSOR;
+yy34:  yych = *++YYCURSOR;
        if(yych != '{') goto yy2;
-yy33:  yych = *++YYCURSOR;
-yy34:
-#line 303
+yy35:  yych = *++YYCURSOR;
+yy36:
+#line 304
        {
        int elements = parse_iv(start + 2);
 
@@ -500,29 +516,29 @@ yy34:
 
        return finish_nested_data(UNSERIALIZE_PASSTHRU);
 }
-yy35:  yych = *++YYCURSOR;
+yy37:  yych = *++YYCURSOR;
        if(yych <= ','){
                if(yych != '+') goto yy2;
        } else {
-               if(yych <= '-') goto yy36;
+               if(yych <= '-') goto yy38;
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy37;
+               if(yych <= '9') goto yy39;
                goto yy2;
        }
-yy36:  yych = *++YYCURSOR;
+yy38:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy37:  ++YYCURSOR;
+yy39:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy38:  if(yych <= '/') goto yy2;
-       if(yych <= '9') goto yy37;
+yy40:  if(yych <= '/') goto yy2;
+       if(yych <= '9') goto yy39;
        if(yych >= ';') goto yy2;
-yy39:  yych = *++YYCURSOR;
+yy41:  yych = *++YYCURSOR;
        if(yych != '"') goto yy2;
-yy40:  yych = *++YYCURSOR;
-yy41:
-#line 283
+yy42:  yych = *++YYCURSOR;
+yy43:
+#line 284
        {
        int len;
        char *str;
@@ -542,192 +558,192 @@ yy41:
        ZVAL_STRINGL(*rval, str, len, 0);
        return 1;
 }
-yy42:  yych = *++YYCURSOR;
+yy44:  yych = *++YYCURSOR;
        if(yych <= '-'){
-               if(yych == '+') goto yy43;
+               if(yych == '+') goto yy45;
                if(yych <= ',') goto yy2;
        } else {
-               if(yych <= '.') goto yy46;
+               if(yych <= '.') goto yy48;
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy44;
+               if(yych <= '9') goto yy46;
                goto yy2;
        }
-yy43:  yych = *++YYCURSOR;
-       if(yych == '.') goto yy46;
+yy45:  yych = *++YYCURSOR;
+       if(yych == '.') goto yy48;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy44:  ++YYCURSOR;
+yy46:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy45:  if(yych <= '/'){
-               if(yych == '.') goto yy56;
+yy47:  if(yych <= '/'){
+               if(yych == '.') goto yy58;
                goto yy2;
        } else {
-               if(yych <= '9') goto yy44;
-               if(yych == ';') goto yy49;
+               if(yych <= '9') goto yy46;
+               if(yych == ';') goto yy51;
                goto yy2;
        }
-yy46:  yych = *++YYCURSOR;
+yy48:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy47:  ++YYCURSOR;
+yy49:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy48:  if(yych <= ';'){
+yy50:  if(yych <= ';'){
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy47;
+               if(yych <= '9') goto yy49;
                if(yych <= ':') goto yy2;
        } else {
                if(yych <= 'E'){
                        if(yych <= 'D') goto yy2;
-                       goto yy51;
+                       goto yy53;
                } else {
-                       if(yych == 'e') goto yy51;
+                       if(yych == 'e') goto yy53;
                        goto yy2;
                }
        }
-yy49:  yych = *++YYCURSOR;
-yy50:
-#line 276
+yy51:  yych = *++YYCURSOR;
+yy52:
+#line 277
        {
        *p = YYCURSOR;
        INIT_PZVAL(*rval);
        ZVAL_DOUBLE(*rval, atof(start + 2));
        return 1;
 }
-yy51:  yych = *++YYCURSOR;
+yy53:  yych = *++YYCURSOR;
        if(yych <= ','){
                if(yych != '+') goto yy2;
        } else {
-               if(yych <= '-') goto yy52;
+               if(yych <= '-') goto yy54;
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy53;
+               if(yych <= '9') goto yy55;
                goto yy2;
        }
-yy52:  yych = *++YYCURSOR;
+yy54:  yych = *++YYCURSOR;
        if(yych <= ','){
-               if(yych == '+') goto yy55;
+               if(yych == '+') goto yy57;
                goto yy2;
        } else {
-               if(yych <= '-') goto yy55;
+               if(yych <= '-') goto yy57;
                if(yych <= '/') goto yy2;
                if(yych >= ':') goto yy2;
        }
-yy53:  ++YYCURSOR;
+yy55:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy54:  if(yych <= '/') goto yy2;
-       if(yych <= '9') goto yy53;
-       if(yych == ';') goto yy49;
+yy56:  if(yych <= '/') goto yy2;
+       if(yych <= '9') goto yy55;
+       if(yych == ';') goto yy51;
        goto yy2;
-yy55:  yych = *++YYCURSOR;
+yy57:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
-       if(yych <= '9') goto yy53;
+       if(yych <= '9') goto yy55;
        goto yy2;
-yy56:  yych = *++YYCURSOR;
+yy58:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy57:  ++YYCURSOR;
+yy59:  ++YYCURSOR;
        if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
        yych = *YYCURSOR;
-yy58:  if(yych <= ';'){
+yy60:  if(yych <= ';'){
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy57;
+               if(yych <= '9') goto yy59;
                if(yych <= ':') goto yy2;
-               goto yy49;
+               goto yy51;
        } else {
                if(yych <= 'E'){
                        if(yych <= 'D') goto yy2;
-                       goto yy51;
+                       goto yy53;
                } else {
-                       if(yych == 'e') goto yy51;
+                       if(yych == 'e') goto yy53;
                        goto yy2;
                }
        }
-yy59:  yych = *++YYCURSOR;
+yy61:  yych = *++YYCURSOR;
        if(yych <= ','){
                if(yych != '+') goto yy2;
        } else {
-               if(yych <= '-') goto yy60;
+               if(yych <= '-') goto yy62;
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy61;
+               if(yych <= '9') goto yy63;
                goto yy2;
        }
-yy60:  yych = *++YYCURSOR;
+yy62:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy61:  ++YYCURSOR;
+yy63:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy62:  if(yych <= '/') goto yy2;
-       if(yych <= '9') goto yy61;
+yy64:  if(yych <= '/') goto yy2;
+       if(yych <= '9') goto yy63;
        if(yych != ';') goto yy2;
-yy63:  yych = *++YYCURSOR;
-yy64:
-#line 269
+yy65:  yych = *++YYCURSOR;
+yy66:
+#line 270
        {
        *p = YYCURSOR;
        INIT_PZVAL(*rval);
        ZVAL_LONG(*rval, parse_iv(start + 2));
        return 1;
 }
-yy65:  yych = *++YYCURSOR;
+yy67:  yych = *++YYCURSOR;
        if(yych <= ','){
                if(yych != '+') goto yy2;
        } else {
-               if(yych <= '-') goto yy66;
+               if(yych <= '-') goto yy68;
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy67;
+               if(yych <= '9') goto yy69;
                goto yy2;
        }
-yy66:  yych = *++YYCURSOR;
+yy68:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy67:  ++YYCURSOR;
+yy69:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy68:  if(yych <= '/') goto yy2;
-       if(yych <= '9') goto yy67;
+yy70:  if(yych <= '/') goto yy2;
+       if(yych <= '9') goto yy69;
        if(yych != ';') goto yy2;
-yy69:  yych = *++YYCURSOR;
-yy70:
-#line 262
+yy71:  yych = *++YYCURSOR;
+yy72:
+#line 263
        {
        *p = YYCURSOR;
        INIT_PZVAL(*rval);
        ZVAL_BOOL(*rval, parse_iv(start + 2));
        return 1;
 }
-yy71:  yych = *++YYCURSOR;
-yy72:
-#line 255
+yy73:  yych = *++YYCURSOR;
+yy74:
+#line 256
        {
        *p = YYCURSOR;
        INIT_PZVAL(*rval);
        ZVAL_NULL(*rval);
        return 1;
 }
-yy73:  yych = *++YYCURSOR;
+yy75:  yych = *++YYCURSOR;
        if(yych <= ','){
                if(yych != '+') goto yy2;
        } else {
-               if(yych <= '-') goto yy74;
+               if(yych <= '-') goto yy76;
                if(yych <= '/') goto yy2;
-               if(yych <= '9') goto yy75;
+               if(yych <= '9') goto yy77;
                goto yy2;
        }
-yy74:  yych = *++YYCURSOR;
+yy76:  yych = *++YYCURSOR;
        if(yych <= '/') goto yy2;
        if(yych >= ':') goto yy2;
-yy75:  ++YYCURSOR;
+yy77:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
-yy76:  if(yych <= '/') goto yy2;
-       if(yych <= '9') goto yy75;
+yy78:  if(yych <= '/') goto yy2;
+       if(yych <= '9') goto yy77;
        if(yych != ';') goto yy2;
-yy77:  yych = *++YYCURSOR;
-yy78:
-#line 236
+yy79:  yych = *++YYCURSOR;
+yy80:
+#line 237
        {
        int id;
 
@@ -747,7 +763,7 @@ yy78:
        return 1;
 }
 }
-#line 399
+#line 406
 
 
        return 0;
index f236f5298483d16c8e98709bf42a442319ef5b20..1f11d3c3ca947345b492d0ec1c01756e773779fa 100644 (file)
@@ -233,6 +233,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
        
        
 /*!re2c
+
 "R:" iv ";"            {
        int id;
 
@@ -394,6 +395,12 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
        return object_common2(UNSERIALIZE_PASSTHRU, elements);
 }
 
+"}" {
+       /* this is the case where we have less data than planned */
+       zend_error(E_NOTICE, "Unexpected end of serialized data");
+       return 0; /* not sure if it should be 0 or 1 here? */
+}
+
 any    { return 0; }
 
 */