/* {{{ proto void SplDoublyLinkedList::unserialize(string serialized) Unserializes storage */ SPL_METHOD(SplDoublyLinkedList, unserialize) { spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); zval *flags, *elem; char *buf; size_t buf_len; const unsigned char *p, *s; php_unserialize_data_t var_hash; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &buf, &buf_len) == FAILURE) { return; } if (buf_len == 0) { return; } s = p = (const unsigned char*)buf; PHP_VAR_UNSERIALIZE_INIT(var_hash); /* flags */ flags = var_tmp_var(&var_hash); if (!php_var_unserialize(flags, &p, s + buf_len, &var_hash) || Z_TYPE_P(flags) != IS_LONG) { goto error; } intern->flags = (int)Z_LVAL_P(flags); /* elements */ while(*p == ':') { ++p; elem = var_tmp_var(&var_hash); if (!php_var_unserialize(elem, &p, s + buf_len, &var_hash)) { goto error; } var_push_dtor(&var_hash, elem); spl_ptr_llist_push(intern->llist, elem); } if (*p != '\0') { goto error; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); return; error: PHP_VAR_UNSERIALIZE_DESTROY(var_hash); zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Error at offset %zd of %zd bytes", ((char*)p - buf), buf_len); return; } /* }}} */
PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval) { zval *tmp_var = var_tmp_var(var_hashx); if (!tmp_var) { return; } ZVAL_COPY(tmp_var, rval); }
int php_ds_pair_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buffer, size_t length, zend_unserialize_data *data) { zval *key, *value; php_unserialize_data_t unserialize_data = (php_unserialize_data_t) data; const unsigned char *pos = buffer; const unsigned char *max = buffer + length; PHP_VAR_UNSERIALIZE_INIT(unserialize_data); key = var_tmp_var(&unserialize_data); if (php_var_unserialize(key, &pos, max, &unserialize_data)) { var_push_dtor(&unserialize_data, key); } else { goto error; } value = var_tmp_var(&unserialize_data); if (php_var_unserialize(value, &pos, max, &unserialize_data)) { var_push_dtor(&unserialize_data, value); } else { goto error; } if (*(++pos) != '\0') { goto error; } ZVAL_DS_PAIR(object, ds_pair_ex(key, value)); PHP_VAR_UNSERIALIZE_DESTROY(unserialize_data); return SUCCESS; error: PHP_VAR_UNSERIALIZE_DESTROY(unserialize_data); UNSERIALIZE_ERROR(); return FAILURE; }
static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements) { HashTable *ht; zend_bool has_wakeup; if (Z_TYPE_P(rval) != IS_OBJECT) { return 0; } has_wakeup = Z_OBJCE_P(rval) != PHP_IC_ENTRY && zend_hash_str_exists(&Z_OBJCE_P(rval)->function_table, "__wakeup", sizeof("__wakeup")-1); ht = Z_OBJPROP_P(rval); if (elements >= (zend_long)(HT_MAX_SIZE - zend_hash_num_elements(ht))) { return 0; } zend_hash_extend(ht, zend_hash_num_elements(ht) + elements, (ht->u.flags & HASH_FLAG_PACKED)); if (!process_nested_data(UNSERIALIZE_PASSTHRU, ht, elements, 1)) { if (has_wakeup) { ZVAL_DEREF(rval); GC_FLAGS(Z_OBJ_P(rval)) |= IS_OBJ_DESTRUCTOR_CALLED; } return 0; } ZVAL_DEREF(rval); if (has_wakeup) { /* Delay __wakeup call until end of serialization */ zval *wakeup_var = var_tmp_var(var_hash); ZVAL_COPY(wakeup_var, rval); Z_EXTRA_P(wakeup_var) = VAR_WAKEUP_FLAG; } return finish_nested_data(UNSERIALIZE_PASSTHRU); }