diff options
author | Stanislav Malyshev <stas@php.net> | 2002-04-28 16:56:33 +0000 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2002-04-28 16:56:33 +0000 |
commit | a57381e3bd1cbb2c5d75e2a456422301399a33fe (patch) | |
tree | ae2cd897fde4b14391e27c62badc84af768ea571 /ext/standard/var.c | |
parent | 245708b0db58cab150ec10f3551c0976514b8aa6 (diff) | |
download | php-git-a57381e3bd1cbb2c5d75e2a456422301399a33fe.tar.gz |
Fix couple of nasty serializer bugs:
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).
Diffstat (limited to 'ext/standard/var.c')
-rw-r--r-- | ext/standard/var.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/ext/standard/var.c b/ext/standard/var.c index 4b8e661aae..0f88fae366 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -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, '}'); |