Bug #14293 Updated: serializer & __sleep()
| From: | bernd@php.net | Date: | Fri, 30 Nov 2001 02:37:42 +0000 |
| Subject: | Bug #14293 Updated: serializer & __sleep() | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-72088@lists.php.net to get a copy of this message | ||
ID: 14293
Updated by: bernd
Reported By: bernd@php.net
Status: Open
Bug Type: Session related
Operating System: linux
Old PHP Version: 4.1.0
PHP Version: 4.2.0
New Comment:
oops...
sorry... i patches i posted aren't working :(
here is (as i hope) the correct one:
--- ../../php4/ext/standard/var.c Sat Nov 10 22:18:34 2001
+++ ext/standard/var.c Fri Nov 30 03:33:49 2001
@@ -198,27 +198,29 @@
int count = zend_hash_num_elements(HASH_OF(retval_ptr));
php_var_serialize_class_name(buf, struc TSRMLS_CC);
- smart_str_append_long(buf, count);
- smart_str_appendl(buf, ":{", 2);
+
if (count > 0) {
char *key;
zval **d, **name;
ulong index;
HashPosition pos;
int i;
-
- zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos);
+ int cundef;
+
+ smart_str buf2={0};
+ cundef=0;
+ zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos);
for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) {
i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, NULL,
&index, 0, &pos);
if (i == HASH_KEY_NON_EXISTANT)
break;
-
+
zend_hash_get_current_data_ex(HASH_OF(retval_ptr),
(void **) &name, &pos);
if (Z_TYPE_PP(name) != IS_STRING) {
@@ -229,14 +231,24 @@
}
if (zend_hash_find(Z_OBJPROP_PP(struc), Z_STRVAL_PP(name),
Z_STRLEN_PP(name) + 1, (void *) &d) == SUCCESS) {
- php_var_serialize_string(buf, Z_STRVAL_PP(name),
+ php_var_serialize_string(&buf2, Z_STRVAL_PP(name),
Z_STRLEN_PP(name));
- php_var_serialize_intern(buf, d, var_hash TSRMLS_CC);
+ php_var_serialize_intern(&buf2, d, var_hash TSRMLS_CC);
+ } else {
+ cundef++;
}
}
+ // if (cundef>0)
+ // php_error(E_WARNING,"__sleep returned %d attributes, but some (%d) were
unset",count,cundef);
+ smart_str_append_long(buf, count-cundef);
+ smart_str_appendl(buf, ":{", 2);
+ smart_str_appendl(buf,buf2.c,buf2.len);
+ smart_str_free(&buf2);
}
+
+
smart_str_appendc(buf, '}');
}
that seems to work... but sascha may fix it his way...
cu
---bernd roemer--- (fumanchi)
Previous Comments:
------------------------------------------------------------------------
[2001-11-29 20:29:06] bernd@php.net
hi...
i found a bug in the serializer-function (current cvs 4.2.0-dev) which results in invalid
serialised-strings. if you serialize an object which uses __sleep() to define the classnamevariables
should be serialized, and some of this variables aren't initialized (isset()==flase),
the serializer won't serialize these vars (OK). BUT he produces invalid strings because he
doesn't use the correct value for the "number of object-attributes".
O:1:"a":3:{s:5:"value";s:1:"a";}
^ ^
3 parts are predicted.. but only 1 is provided. :(
an example-script:
<?php
class a {
function a() {
$this->value="a";
}
function __sleep() {
return(array('a','b','value'));
}
}
$a=new a();
echo serialize($a);
?>
ok.. now.. i found two differend patches:
the first (not my favourite) simply serializes uninitialized variables if they had bool(false) as
value.
-----------------------------------------------------------
--- ../../php4/ext/standard/var.c Sat Nov 10 22:18:34 2001
+++ ext/standard/var.c Fri Nov 30 01:22:05 2001
@@ -198,27 +198,34 @@
int count = zend_hash_num_elements(HASH_OF(retval_ptr));
php_var_serialize_class_name(buf, struc TSRMLS_CC);
- smart_str_append_long(buf, count);
- smart_str_appendl(buf, ":{", 2);
+
if (count > 0) {
char *key;
zval **d, **name;
ulong index;
HashPosition pos;
int i;
+ int cundef;
+ smart_str_append_long(buf, count);
+ smart_str_appendl(buf, ":{", 2);
+
+ cundef=0;
zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos);
-
for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) {
i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, NULL,
&index, 0, &pos);
- if (i == HASH_KEY_NON_EXISTANT)
+ if (i == HASH_KEY_NON_EXISTANT) {
+ php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
+ smart_str_appendl(buf, "b:0;", 4);
+ cundef++;
break;
-
+ }
+
zend_hash_get_current_data_ex(HASH_OF(retval_ptr),
(void **) &name, &pos);
if (Z_TYPE_PP(name) != IS_STRING) {
@@ -234,9 +241,13 @@
Z_STRLEN_PP(name));
php_var_serialize_intern(buf, d, var_hash TSRMLS_CC);
}
}
+ if (cundef>0)
+ php_error(E_WARNING,"__sleep returned %d attributes, but some (%d) were
unset",count,cundef);
}
+
+
smart_str_appendc(buf, '}');
}
the second (my favourite) just puts the correct value for number of psrts in the result:
-----------------------------------------------------------
--- ../../php4/ext/standard/var.c Sat Nov 10 22:18:34 2001
+++ ext/standard/var.c Fri Nov 30 01:31:50 2001
@@ -198,27 +198,33 @@
int count = zend_hash_num_elements(HASH_OF(retval_ptr));
php_var_serialize_class_name(buf, struc TSRMLS_CC);
- smart_str_append_long(buf, count);
- smart_str_appendl(buf, ":{", 2);
+
if (count > 0) {
char *key;
zval **d, **name;
ulong index;
HashPosition pos;
int i;
-
- zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos);
+ int cundef;
+
+ smart_str buf2={0};
+ cundef=0;
+ zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos);
for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) {
i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, NULL,
&index, 0, &pos);
- if (i == HASH_KEY_NON_EXISTANT)
+ if (i == HASH_KEY_NON_EXISTANT) {
+// php_var_serialize_string(&buf2, Z_STRVAL_PP(name), Z_STRLEN_PP(name));
+// smart_str_appendl(&buf2, "b:0;", 4);
+ cundef++;
break;
-
+ }
+
zend_hash_get_current_data_ex(HASH_OF(retval_ptr),
(void **) &name, &pos);
if (Z_TYPE_PP(name) != IS_STRING) {
@@ -229,14 +235,22 @@
}
if (zend_hash_find(Z_OBJPROP_PP(struc), Z_STRVAL_PP(name),
Z_STRLEN_PP(name) + 1, (void *) &d) == SUCCESS) {
- php_var_serialize_string(buf, Z_STRVAL_PP(name),
+ php_var_serialize_string(&buf2, Z_STRVAL_PP(name),
Z_STRLEN_PP(name));
- php_var_serialize_intern(buf, d, var_hash TSRMLS_CC);
+ php_var_serialize_intern(&buf2, d, var_hash TSRMLS_CC);
}
}
+ if (cundef>0)
+ php_error(E_WARNING,"__sleep returned %d attributes, but some (%d) were
unset",count,cundef);
+ smart_str_append_long(buf, count-cundef);
+ smart_str_appendl(buf, ":{", 2);
+ smart_str_appendl(buf,buf2.c,buf2.len);
+ smart_str_free(&buf2);
}
+
+
smart_str_appendc(buf, '}');
}
regards
---bernd roemer--- (fumanchi)
------------------------------------------------------------------------
Edit this bug report at http://bugs.php.net/?id=14293&edit=1