static void zend_file_cache_unserialize_hash(HashTable *ht, zend_persistent_script *script, void *buf, unserialize_callback_t func, dtor_func_t dtor) { Bucket *p, *end; ht->pDestructor = dtor; if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) { HT_SET_DATA_ADDR(ht, &uninitialized_bucket); return; } if (IS_UNSERIALIZED(ht->arData)) { return; } UNSERIALIZE_PTR(ht->arData); p = ht->arData; end = p + ht->nNumUsed; while (p < end) { if (Z_TYPE(p->val) != IS_UNDEF) { UNSERIALIZE_STR(p->key); func(&p->val, script, buf); } p++; } }
static void zend_file_cache_unserialize_prop_info(zval *zv, zend_persistent_script *script, void *buf) { if (!IS_UNSERIALIZED(Z_PTR_P(zv))) { zend_property_info *prop; UNSERIALIZE_PTR(Z_PTR_P(zv)); prop = Z_PTR_P(zv); if (prop->ce && !IS_UNSERIALIZED(prop->ce)) { UNSERIALIZE_PTR(prop->ce); } if (prop->name && !IS_UNSERIALIZED(prop->name)) { UNSERIALIZE_STR(prop->name); } if (prop->doc_comment && !IS_UNSERIALIZED(prop->doc_comment)) { UNSERIALIZE_STR(prop->doc_comment); } } }
static void zend_file_cache_unserialize(zend_persistent_script *script, void *buf) { script->mem = buf; UNSERIALIZE_STR(script->script.filename); zend_file_cache_unserialize_hash(&script->script.class_table, script, buf, zend_file_cache_unserialize_class, ZEND_CLASS_DTOR); zend_file_cache_unserialize_hash(&script->script.function_table, script, buf, zend_file_cache_unserialize_func, ZEND_FUNCTION_DTOR); zend_file_cache_unserialize_op_array(&script->script.main_op_array, script, buf); UNSERIALIZE_PTR(script->arena_mem); }
static void zend_file_cache_unserialize_zval(zval *zv, zend_persistent_script *script, void *buf) { switch (Z_TYPE_P(zv)) { case IS_STRING: case IS_CONSTANT: if (!IS_UNSERIALIZED(Z_STR_P(zv))) { UNSERIALIZE_STR(Z_STR_P(zv)); } break; case IS_ARRAY: if (!IS_UNSERIALIZED(Z_ARR_P(zv))) { HashTable *ht; UNSERIALIZE_PTR(Z_ARR_P(zv)); ht = Z_ARR_P(zv); zend_file_cache_unserialize_hash(ht, script, buf, zend_file_cache_unserialize_zval, ZVAL_PTR_DTOR); } break; case IS_REFERENCE: if (!IS_UNSERIALIZED(Z_REF_P(zv))) { zend_reference *ref; UNSERIALIZE_PTR(Z_REF_P(zv)); ref = Z_REF_P(zv); zend_file_cache_unserialize_zval(&ref->val, script, buf); } break; case IS_CONSTANT_AST: if (!IS_UNSERIALIZED(Z_AST_P(zv))) { zend_ast_ref *ast; UNSERIALIZE_PTR(Z_AST_P(zv)); ast = Z_AST_P(zv); if (!IS_UNSERIALIZED(ast->ast)) { ast->ast = zend_file_cache_unserialize_ast(ast->ast, script, buf); } } break; } }
static void zend_file_cache_unserialize_class_constant(zval *zv, zend_persistent_script *script, void *buf) { if (!IS_UNSERIALIZED(Z_PTR_P(zv))) { zend_class_constant *c; UNSERIALIZE_PTR(Z_PTR_P(zv)); c = Z_PTR_P(zv); zend_file_cache_unserialize_zval(&c->value, script, buf); if (c->ce && !IS_UNSERIALIZED(c->ce)) { UNSERIALIZE_PTR(c->ce); } if (c->doc_comment && !IS_UNSERIALIZED(c->doc_comment)) { UNSERIALIZE_STR(c->doc_comment); } } }
static void zend_file_cache_unserialize_op_array(zend_op_array *op_array, zend_persistent_script *script, void *buf) { if (op_array->static_variables && !IS_UNSERIALIZED(op_array->static_variables)) { HashTable *ht; UNSERIALIZE_PTR(op_array->static_variables); ht = op_array->static_variables; zend_file_cache_unserialize_hash(ht, script, buf, zend_file_cache_unserialize_zval, ZVAL_PTR_DTOR); } if (op_array->literals && !IS_UNSERIALIZED(op_array->literals)) { zval *p, *end; UNSERIALIZE_PTR(op_array->literals); p = op_array->literals; end = p + op_array->last_literal; while (p < end) { zend_file_cache_unserialize_zval(p, script, buf); p++; } } if (!IS_UNSERIALIZED(op_array->opcodes)) { zend_op *opline, *end; UNSERIALIZE_PTR(op_array->opcodes); opline = op_array->opcodes; end = opline + op_array->last; while (opline < end) { # if ZEND_USE_ABS_CONST_ADDR if (opline->op1_type == IS_CONST) { UNSERIALIZE_PTR(opline->op1.zv); } if (opline->op2_type == IS_CONST) { UNSERIALIZE_PTR(opline->op2.zv); } # endif # if ZEND_USE_ABS_JMP_ADDR switch (opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: UNSERIALIZE_PTR(opline->op1.jmp_addr); break; case ZEND_JMPZNZ: /* relative extended_value don't have to be changed */ /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: UNSERIALIZE_PTR(opline->op2.jmp_addr); break; case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: /* relative extended_value don't have to be changed */ break; } # endif zend_deserialize_opcode_handler(opline); opline++; } if (op_array->arg_info) { zend_arg_info *p, *end; UNSERIALIZE_PTR(op_array->arg_info); p = op_array->arg_info; end = p + op_array->num_args; if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { p--; } if (op_array->fn_flags & ZEND_ACC_VARIADIC) { end++; } while (p < end) { if (!IS_UNSERIALIZED(p->name)) { UNSERIALIZE_STR(p->name); } if (!IS_UNSERIALIZED(p->class_name)) { UNSERIALIZE_STR(p->class_name); } p++; } } if (op_array->vars) { zend_string **p, **end; UNSERIALIZE_PTR(op_array->vars); p = op_array->vars; end = p + op_array->last_var; while (p < end) { if (!IS_UNSERIALIZED(*p)) { UNSERIALIZE_STR(*p); } p++; } } UNSERIALIZE_STR(op_array->function_name); UNSERIALIZE_STR(op_array->filename); UNSERIALIZE_PTR(op_array->live_range); UNSERIALIZE_PTR(op_array->scope); UNSERIALIZE_STR(op_array->doc_comment); UNSERIALIZE_PTR(op_array->try_catch_array); UNSERIALIZE_PTR(op_array->prototype); } }
static void zend_file_cache_unserialize_class(zval *zv, zend_persistent_script *script, void *buf) { zend_class_entry *ce; UNSERIALIZE_PTR(Z_PTR_P(zv)); ce = Z_PTR_P(zv); UNSERIALIZE_STR(ce->name); zend_file_cache_unserialize_hash(&ce->function_table, script, buf, zend_file_cache_unserialize_func, ZEND_FUNCTION_DTOR); if (ce->default_properties_table) { zval *p, *end; UNSERIALIZE_PTR(ce->default_properties_table); p = ce->default_properties_table; end = p + ce->default_properties_count; while (p < end) { zend_file_cache_unserialize_zval(p, script, buf); p++; } } if (ce->default_static_members_table) { zval *p, *end; UNSERIALIZE_PTR(ce->default_static_members_table); p = ce->default_static_members_table; end = p + ce->default_static_members_count; while (p < end) { zend_file_cache_unserialize_zval(p, script, buf); p++; } } zend_file_cache_unserialize_hash(&ce->constants_table, script, buf, zend_file_cache_unserialize_class_constant, NULL); UNSERIALIZE_STR(ce->info.user.filename); UNSERIALIZE_STR(ce->info.user.doc_comment); zend_file_cache_unserialize_hash(&ce->properties_info, script, buf, zend_file_cache_unserialize_prop_info, ZVAL_PTR_DTOR); if (ce->trait_aliases) { zend_trait_alias **p, *q; UNSERIALIZE_PTR(ce->trait_aliases); p = ce->trait_aliases; while (*p) { UNSERIALIZE_PTR(*p); q = *p; if (q->trait_method) { zend_trait_method_reference *m; UNSERIALIZE_PTR(q->trait_method); m = q->trait_method; if (m->method_name) { UNSERIALIZE_STR(m->method_name); } if (m->class_name) { UNSERIALIZE_STR(m->class_name); } } if (q->alias) { UNSERIALIZE_STR(q->alias); } p++; } } if (ce->trait_precedences) { zend_trait_precedence **p, *q; UNSERIALIZE_PTR(ce->trait_precedences); p = ce->trait_precedences; while (*p) { UNSERIALIZE_PTR(*p); q = *p; if (q->trait_method) { zend_trait_method_reference *m; UNSERIALIZE_PTR(q->trait_method); m = q->trait_method; if (m->method_name) { UNSERIALIZE_STR(m->method_name); } if (m->class_name) { UNSERIALIZE_STR(m->class_name); } } if (q->exclude_from_classes) { zend_string **s; UNSERIALIZE_PTR(q->exclude_from_classes); s = (zend_string**)q->exclude_from_classes; while (*s) { UNSERIALIZE_STR(*s); s++; } } p++; } } UNSERIALIZE_PTR(ce->parent); UNSERIALIZE_PTR(ce->constructor); UNSERIALIZE_PTR(ce->destructor); UNSERIALIZE_PTR(ce->clone); UNSERIALIZE_PTR(ce->__get); UNSERIALIZE_PTR(ce->__set); UNSERIALIZE_PTR(ce->__call); UNSERIALIZE_PTR(ce->serialize_func); UNSERIALIZE_PTR(ce->unserialize_func); UNSERIALIZE_PTR(ce->__isset); UNSERIALIZE_PTR(ce->__unset); UNSERIALIZE_PTR(ce->__tostring); UNSERIALIZE_PTR(ce->__callstatic); UNSERIALIZE_PTR(ce->__debugInfo); if (UNEXPECTED((ce->ce_flags & ZEND_ACC_ANON_CLASS))) { ce->serialize = zend_class_serialize_deny; ce->unserialize = zend_class_unserialize_deny; } }
static void zend_file_cache_unserialize_op_array(zend_op_array *op_array, zend_persistent_script *script, void *buf) { if (op_array->static_variables && !IS_UNSERIALIZED(op_array->static_variables)) { HashTable *ht; UNSERIALIZE_PTR(op_array->static_variables); ht = op_array->static_variables; zend_file_cache_unserialize_hash(ht, script, buf, zend_file_cache_unserialize_zval, ZVAL_PTR_DTOR); } if (op_array->refcount) { op_array->refcount = NULL; UNSERIALIZE_PTR(op_array->literals); UNSERIALIZE_PTR(op_array->opcodes); UNSERIALIZE_PTR(op_array->arg_info); UNSERIALIZE_PTR(op_array->vars); UNSERIALIZE_STR(op_array->function_name); UNSERIALIZE_STR(op_array->filename); UNSERIALIZE_PTR(op_array->live_range); UNSERIALIZE_PTR(op_array->scope); UNSERIALIZE_STR(op_array->doc_comment); UNSERIALIZE_PTR(op_array->try_catch_array); UNSERIALIZE_PTR(op_array->prototype); return; } if (op_array->literals && !IS_UNSERIALIZED(op_array->literals)) { zval *p, *end; UNSERIALIZE_PTR(op_array->literals); p = op_array->literals; end = p + op_array->last_literal; while (p < end) { zend_file_cache_unserialize_zval(p, script, buf); p++; } } if (!IS_UNSERIALIZED(op_array->opcodes)) { zend_op *opline, *end; UNSERIALIZE_PTR(op_array->opcodes); opline = op_array->opcodes; end = opline + op_array->last; while (opline < end) { #if ZEND_USE_ABS_CONST_ADDR if (opline->op1_type == IS_CONST) { UNSERIALIZE_PTR(opline->op1.zv); } if (opline->op2_type == IS_CONST) { UNSERIALIZE_PTR(opline->op2.zv); } #else if (opline->op1_type == IS_CONST) { ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, opline->op1); } if (opline->op2_type == IS_CONST) { ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, opline->op2); } #endif #if ZEND_USE_ABS_JMP_ADDR switch (opline->opcode) { case ZEND_JMP: case ZEND_FAST_CALL: UNSERIALIZE_PTR(opline->op1.jmp_addr); break; case ZEND_JMPZNZ: /* relative extended_value don't have to be changed */ /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: UNSERIALIZE_PTR(opline->op2.jmp_addr); break; case ZEND_DECLARE_ANON_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: case ZEND_SWITCH_LONG: case ZEND_SWITCH_STRING: /* relative extended_value don't have to be changed */ break; } #endif zend_deserialize_opcode_handler(opline); opline++; } if (op_array->arg_info) { zend_arg_info *p, *end; UNSERIALIZE_PTR(op_array->arg_info); p = op_array->arg_info; end = p + op_array->num_args; if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { p--; } if (op_array->fn_flags & ZEND_ACC_VARIADIC) { end++; } while (p < end) { if (!IS_UNSERIALIZED(p->name)) { UNSERIALIZE_STR(p->name); } if (p->type & (Z_UL(1) << (sizeof(zend_type)*8-1))) { /* type is class */ zend_bool allow_null = (p->type & (Z_UL(1) << (sizeof(zend_type)*8-2))) != 0; /* type allow null */ zend_string *type_name = (zend_string*)(p->type & ~(((Z_UL(1) << (sizeof(zend_type)*8-1))) | ((Z_UL(1) << (sizeof(zend_type)*8-2))))); UNSERIALIZE_STR(type_name); p->type = ZEND_TYPE_ENCODE_CLASS(type_name, allow_null); } p++; } } if (op_array->vars) { zend_string **p, **end; UNSERIALIZE_PTR(op_array->vars); p = op_array->vars; end = p + op_array->last_var; while (p < end) { if (!IS_UNSERIALIZED(*p)) { UNSERIALIZE_STR(*p); } p++; } } UNSERIALIZE_STR(op_array->function_name); UNSERIALIZE_STR(op_array->filename); UNSERIALIZE_PTR(op_array->live_range); UNSERIALIZE_PTR(op_array->scope); UNSERIALIZE_STR(op_array->doc_comment); UNSERIALIZE_PTR(op_array->try_catch_array); UNSERIALIZE_PTR(op_array->prototype); } }