Linux server.kiran-academy.com 3.10.0-1160.108.1.el7.x86_64 #1 SMP Thu Jan 25 16:17:31 UTC 2024 x86_64
Apache/2.4.57 (Unix) OpenSSL/1.0.2k-fips
: 194.233.91.196 | : 216.73.216.172
Cant Read [ /etc/named.conf ]
7.4.32
finalho
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
usr /
local /
src /
apcu-5.1.19 /
[ HOME SHELL ]
Name
Size
Permission
Action
.libs
[ DIR ]
drwxr-xr-x
autom4te.cache
[ DIR ]
drwxr-xr-x
build
[ DIR ]
drwxr-xr-x
include
[ DIR ]
drwxr-xr-x
modules
[ DIR ]
drwxr-xr-x
tests
[ DIR ]
drwxr-xr-x
INSTALL
13.63
KB
-rw-rw-r--
LICENSE
3.14
KB
-rw-rw-r--
Makefile
13.36
KB
-rw-r--r--
Makefile.frag
270
B
-rw-rw-r--
Makefile.fragments
0
B
-rw-r--r--
Makefile.objects
4.18
KB
-rw-r--r--
NOTICE
1.7
KB
-rw-rw-r--
README.md
1.47
KB
-rw-rw-r--
TECHNOTES.txt
13.04
KB
-rw-rw-r--
apc.c
4.33
KB
-rw-rw-r--
apc.dep
5.33
KB
-rw-r--r--
apc.h
6.09
KB
-rw-rw-r--
apc.lo
297
B
-rw-r--r--
apc.php
37.09
KB
-rw-rw-r--
apc_api.h
1.24
KB
-rw-rw-r--
apc_arginfo.h
113
B
-rw-rw-r--
apc_cache.c
31.24
KB
-rw-rw-r--
apc_cache.dep
6.14
KB
-rw-r--r--
apc_cache.h
1.92
KB
-rw-rw-r--
apc_cache.lo
309
B
-rw-r--r--
apc_cache_api.h
11.85
KB
-rw-rw-r--
apc_globals.h
3.55
KB
-rw-rw-r--
apc_iterator.c
15.88
KB
-rw-rw-r--
apc_iterator.dep
6.29
KB
-rw-r--r--
apc_iterator.h
3.79
KB
-rw-rw-r--
apc_iterator.lo
315
B
-rw-r--r--
apc_iterator.stub.php
753
B
-rw-rw-r--
apc_iterator_arginfo.h
2.29
KB
-rw-rw-r--
apc_iterator_legacy_arginfo.h
2.11
KB
-rw-rw-r--
apc_lock.c
7.1
KB
-rw-rw-r--
apc_lock.dep
5.09
KB
-rw-r--r--
apc_lock.h
1.27
KB
-rw-rw-r--
apc_lock.lo
307
B
-rw-r--r--
apc_lock_api.h
4.54
KB
-rw-rw-r--
apc_mmap.c
4.26
KB
-rw-rw-r--
apc_mmap.dep
5.22
KB
-rw-r--r--
apc_mmap.h
1.94
KB
-rw-rw-r--
apc_mmap.lo
307
B
-rw-r--r--
apc_mutex.c
2.24
KB
-rw-rw-r--
apc_mutex.dep
5.05
KB
-rw-r--r--
apc_mutex.h
2.25
KB
-rw-rw-r--
apc_mutex.lo
309
B
-rw-r--r--
apc_persist.c
17.47
KB
-rw-rw-r--
apc_persist.dep
5.27
KB
-rw-r--r--
apc_persist.lo
313
B
-rw-r--r--
apc_php.h
2.79
KB
-rw-rw-r--
apc_serializer.h
2.96
KB
-rw-rw-r--
apc_shm.c
3.57
KB
-rw-rw-r--
apc_shm.dep
5.13
KB
-rw-r--r--
apc_shm.h
2.04
KB
-rw-rw-r--
apc_shm.lo
305
B
-rw-r--r--
apc_signal.c
6.68
KB
-rw-rw-r--
apc_signal.dep
5.6
KB
-rw-r--r--
apc_signal.h
1.8
KB
-rw-rw-r--
apc_signal.lo
311
B
-rw-r--r--
apc_sma.c
16.45
KB
-rw-rw-r--
apc_sma.dep
5.46
KB
-rw-r--r--
apc_sma.h
1.75
KB
-rw-rw-r--
apc_sma.lo
305
B
-rw-r--r--
apc_sma_api.h
5.48
KB
-rw-rw-r--
apc_stack.c
2.9
KB
-rw-rw-r--
apc_stack.dep
5.05
KB
-rw-r--r--
apc_stack.h
2.22
KB
-rw-rw-r--
apc_stack.lo
309
B
-rw-r--r--
apc_strings.h
1.45
KB
-rw-rw-r--
apc_windows_srwlock_kernel.c
1.93
KB
-rw-rw-r--
apc_windows_srwlock_kernel.h
1.8
KB
-rw-rw-r--
apcu.la
780
B
-rw-r--r--
config.h
2.03
KB
-rw-r--r--
config.h.in
1.89
KB
-rw-r--r--
config.log
23.11
KB
-rw-r--r--
config.m4
9.39
KB
-rw-rw-r--
config.nice
190
B
-rwxr-xr-x
config.status
21
KB
-rwxr-xr-x
config.w32
1.06
KB
-rw-rw-r--
configure
448.17
KB
-rwxr-xr-x
configure.ac
5.17
KB
-rw-r--r--
libtool
205.98
KB
-rwxr-xr-x
php74_shim.h
4.19
KB
-rw-rw-r--
php_apc.c
21.39
KB
-rw-rw-r--
php_apc.dep
6.93
KB
-rw-r--r--
php_apc.h
2.23
KB
-rw-rw-r--
php_apc.lo
305
B
-rw-r--r--
php_apc.stub.php
1.23
KB
-rw-rw-r--
php_apc_arginfo.h
3.71
KB
-rw-rw-r--
php_apc_legacy_arginfo.h
2.91
KB
-rw-rw-r--
run-tests.php
139.39
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : apc_persist.c
/* +----------------------------------------------------------------------+ | APCu | +----------------------------------------------------------------------+ | Copyright (c) 2018 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Nikita Popov <nikic@php.net> | +----------------------------------------------------------------------+ */ #include "apc.h" #include "apc_cache.h" #if PHP_VERSION_ID < 70300 # define GC_SET_REFCOUNT(ref, rc) (GC_REFCOUNT(ref) = (rc)) # define GC_ADDREF(ref) GC_REFCOUNT(ref)++ # define GC_SET_PERSISTENT_TYPE(ref, type) (GC_TYPE_INFO(ref) = type) # if PHP_VERSION_ID < 70200 # define GC_ARRAY IS_ARRAY # else # define GC_ARRAY (IS_ARRAY | (GC_COLLECTABLE << GC_FLAGS_SHIFT)) # endif #else # define GC_SET_PERSISTENT_TYPE(ref, type) \ (GC_TYPE_INFO(ref) = type | (GC_PERSISTENT << GC_FLAGS_SHIFT)) #endif /* * PERSIST: Copy from request memory to SHM. */ typedef struct _apc_persist_context_t { /* Serializer to use */ apc_serializer_t *serializer; /* Computed size of the needed SMA allocation */ size_t size; /* Whether or not we may have to memoize refcounted addresses */ zend_bool memoization_needed; /* Whether to force serialization of the top-level value */ zend_bool force_serialization; /* Serialized object/array string, in case there can only be one */ unsigned char *serialized_str; size_t serialized_str_len; /* Whole SMA allocation */ char *alloc; /* Current position in allocation */ char *alloc_cur; /* HashTable storing refcounteds for which the size has already been counted. */ HashTable already_counted; /* HashTable storing already allocated refcounteds. Pointers to refcounteds are stored. */ HashTable already_allocated; } apc_persist_context_t; #define ADD_SIZE(sz) ctxt->size += ZEND_MM_ALIGNED_SIZE(sz) #define ADD_SIZE_STR(len) ADD_SIZE(_ZSTR_STRUCT_SIZE(len)) #define ALLOC(sz) apc_persist_alloc(ctxt, sz) #define COPY(val, sz) apc_persist_alloc_copy(ctxt, val, sz) static zend_bool apc_persist_calc_zval( apc_persist_context_t *ctxt, const zval *zv, zend_bool top_level); static void apc_persist_copy_zval_impl(apc_persist_context_t *ctxt, zval *zv); static inline void apc_persist_copy_zval(apc_persist_context_t *ctxt, zval *zv) { /* No data apart from the zval itself */ if (Z_TYPE_P(zv) < IS_STRING) { return; } apc_persist_copy_zval_impl(ctxt, zv); } void apc_persist_init_context(apc_persist_context_t *ctxt, apc_serializer_t *serializer) { ctxt->serializer = serializer; ctxt->size = 0; ctxt->memoization_needed = 0; ctxt->force_serialization = 0; ctxt->serialized_str = NULL; ctxt->serialized_str_len = 0; ctxt->alloc = NULL; ctxt->alloc_cur = NULL; } void apc_persist_destroy_context(apc_persist_context_t *ctxt) { if (ctxt->memoization_needed) { zend_hash_destroy(&ctxt->already_counted); zend_hash_destroy(&ctxt->already_allocated); } if (ctxt->serialized_str) { efree(ctxt->serialized_str); } } static zend_bool apc_persist_calc_memoize(apc_persist_context_t *ctxt, void *ptr) { zval tmp; if (!ctxt->memoization_needed) { return 0; } if (zend_hash_index_exists(&ctxt->already_counted, (uintptr_t) ptr)) { return 1; } ZVAL_NULL(&tmp); zend_hash_index_add_new(&ctxt->already_counted, (uintptr_t) ptr, &tmp); return 0; } static zend_bool apc_persist_calc_ht(apc_persist_context_t *ctxt, const HashTable *ht) { uint32_t idx; ADD_SIZE(sizeof(HashTable)); if (ht->nNumUsed == 0) { return 1; } /* TODO Too sparse hashtables could be compacted here */ ADD_SIZE(HT_USED_SIZE(ht)); for (idx = 0; idx < ht->nNumUsed; idx++) { Bucket *p = ht->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; /* This can only happen if $GLOBALS is placed in the cache. * Don't bother with this edge-case, fall back to serialization. */ if (Z_TYPE(p->val) == IS_INDIRECT) { ctxt->force_serialization = 1; return 0; } /* TODO These strings can be reused if (p->key && !apc_persist_calc_is_handled(ctxt, (zend_refcounted *) p->key)) { ADD_SIZE_STR(ZSTR_LEN(p->key)); }*/ if (p->key) { ADD_SIZE_STR(ZSTR_LEN(p->key)); } if (!apc_persist_calc_zval(ctxt, &p->val, 0)) { return 0; } } return 1; } static zend_bool apc_persist_calc_serialize(apc_persist_context_t *ctxt, const zval *zv) { unsigned char *buf = NULL; size_t buf_len = 0; apc_serialize_t serialize = APC_SERIALIZER_NAME(php); void *config = NULL; if (ctxt->serializer) { serialize = ctxt->serializer->serialize; config = ctxt->serializer->config; } if (!serialize(&buf, &buf_len, zv, config)) { return 0; } /* We only ever serialize the top-level value, memoization cannot be needed */ ZEND_ASSERT(!ctxt->memoization_needed); ctxt->serialized_str = buf; ctxt->serialized_str_len = buf_len; ADD_SIZE_STR(buf_len); return 1; } static zend_bool apc_persist_calc_zval( apc_persist_context_t *ctxt, const zval *zv, zend_bool top_level) { if (Z_TYPE_P(zv) < IS_STRING) { /* No data apart from the zval itself */ return 1; } if (ctxt->force_serialization) { return apc_persist_calc_serialize(ctxt, zv); } if (apc_persist_calc_memoize(ctxt, Z_COUNTED_P(zv))) { return 1; } switch (Z_TYPE_P(zv)) { case IS_STRING: ADD_SIZE_STR(Z_STRLEN_P(zv)); return 1; case IS_ARRAY: if (!ctxt->serializer) { return apc_persist_calc_ht(ctxt, Z_ARRVAL_P(zv)); } /* break missing intentionally */ case IS_OBJECT: if (!top_level) { ctxt->force_serialization = 1; return 0; } return apc_persist_calc_serialize(ctxt, zv); case IS_REFERENCE: ADD_SIZE(sizeof(zend_reference)); return apc_persist_calc_zval(ctxt, Z_REFVAL_P(zv), 0); case IS_RESOURCE: apc_warning("Cannot store resources in apcu cache"); return 0; default: ZEND_ASSERT(0); return 0; } } static zend_bool apc_persist_calc(apc_persist_context_t *ctxt, const apc_cache_entry_t *entry) { ADD_SIZE(sizeof(apc_cache_entry_t)); ADD_SIZE_STR(ZSTR_LEN(entry->key)); return apc_persist_calc_zval(ctxt, &entry->val, 1); } static inline void *apc_persist_get_already_allocated(apc_persist_context_t *ctxt, void *ptr) { if (ctxt->memoization_needed) { return zend_hash_index_find_ptr(&ctxt->already_allocated, (uintptr_t) ptr); } return NULL; } static inline void apc_persist_add_already_allocated( apc_persist_context_t *ctxt, const void *old_ptr, void *new_ptr) { if (ctxt->memoization_needed) { zend_hash_index_add_new_ptr(&ctxt->already_allocated, (uintptr_t) old_ptr, new_ptr); } } static inline void *apc_persist_alloc(apc_persist_context_t *ctxt, size_t size) { void *ptr = ctxt->alloc_cur; ctxt->alloc_cur += ZEND_MM_ALIGNED_SIZE(size); ZEND_ASSERT(ctxt->alloc_cur <= ctxt->alloc + ctxt->size); return ptr; } static inline void *apc_persist_alloc_copy( apc_persist_context_t *ctxt, const void *val, size_t size) { void *ptr = apc_persist_alloc(ctxt, size); memcpy(ptr, val, size); return ptr; } static zend_string *apc_persist_copy_cstr( apc_persist_context_t *ctxt, const char *orig_buf, size_t buf_len, zend_ulong hash) { zend_string *str = ALLOC(_ZSTR_STRUCT_SIZE(buf_len)); GC_SET_REFCOUNT(str, 1); GC_SET_PERSISTENT_TYPE(str, IS_STRING); ZSTR_H(str) = hash; ZSTR_LEN(str) = buf_len; memcpy(ZSTR_VAL(str), orig_buf, buf_len); ZSTR_VAL(str)[buf_len] = '\0'; zend_string_hash_val(str); return str; } static zend_string *apc_persist_copy_zstr( apc_persist_context_t *ctxt, const zend_string *orig_str) { zend_string *str = apc_persist_copy_cstr( ctxt, ZSTR_VAL(orig_str), ZSTR_LEN(orig_str), ZSTR_H(orig_str)); apc_persist_add_already_allocated(ctxt, orig_str, str); return str; } static zend_reference *apc_persist_copy_ref( apc_persist_context_t *ctxt, const zend_reference *orig_ref) { zend_reference *ref = ALLOC(sizeof(zend_reference)); apc_persist_add_already_allocated(ctxt, orig_ref, ref); GC_SET_REFCOUNT(ref, 1); GC_SET_PERSISTENT_TYPE(ref, IS_REFERENCE); #if PHP_VERSION_ID >= 70400 ref->sources.ptr = NULL; #endif ZVAL_COPY_VALUE(&ref->val, &orig_ref->val); apc_persist_copy_zval(ctxt, &ref->val); return ref; } static const uint32_t uninitialized_bucket[-HT_MIN_MASK] = {HT_INVALID_IDX, HT_INVALID_IDX}; static zend_array *apc_persist_copy_ht(apc_persist_context_t *ctxt, const HashTable *orig_ht) { HashTable *ht = COPY(orig_ht, sizeof(HashTable)); uint32_t idx; apc_persist_add_already_allocated(ctxt, orig_ht, ht); GC_SET_REFCOUNT(ht, 1); GC_SET_PERSISTENT_TYPE(ht, GC_ARRAY); /* Immutable arrays from opcache may lack a dtor and the apply protection flag. */ ht->pDestructor = ZVAL_PTR_DTOR; #if PHP_VERSION_ID < 70300 ht->u.flags |= HASH_FLAG_APPLY_PROTECTION; #endif ht->u.flags |= HASH_FLAG_STATIC_KEYS; if (ht->nNumUsed == 0) { #if PHP_VERSION_ID >= 70400 ht->u.flags = HASH_FLAG_UNINITIALIZED; #else ht->u.flags &= ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED); #endif ht->nNextFreeElement = 0; ht->nTableMask = HT_MIN_MASK; HT_SET_DATA_ADDR(ht, &uninitialized_bucket); return ht; } ht->nNextFreeElement = 0; ht->nInternalPointer = HT_INVALID_IDX; HT_SET_DATA_ADDR(ht, COPY(HT_GET_DATA_ADDR(ht), HT_USED_SIZE(ht))); for (idx = 0; idx < ht->nNumUsed; idx++) { Bucket *p = ht->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; if (ht->nInternalPointer == HT_INVALID_IDX) { ht->nInternalPointer = idx; } if (p->key) { p->key = apc_persist_copy_zstr(ctxt, p->key); ht->u.flags &= ~HASH_FLAG_STATIC_KEYS; } else if ((zend_long) p->h >= (zend_long) ht->nNextFreeElement) { ht->nNextFreeElement = p->h + 1; } apc_persist_copy_zval(ctxt, &p->val); } return ht; } static void apc_persist_copy_serialize( apc_persist_context_t *ctxt, zval *zv) { zend_string *str; zend_uchar orig_type = Z_TYPE_P(zv); ZEND_ASSERT(orig_type == IS_ARRAY || orig_type == IS_OBJECT); ZEND_ASSERT(!ctxt->memoization_needed); ZEND_ASSERT(ctxt->serialized_str); str = apc_persist_copy_cstr(ctxt, (char *) ctxt->serialized_str, ctxt->serialized_str_len, 0); /* Store as PTR type to distinguish from other strings */ ZVAL_PTR(zv, str); } static void apc_persist_copy_zval_impl(apc_persist_context_t *ctxt, zval *zv) { void *ptr; if (ctxt->force_serialization) { apc_persist_copy_serialize(ctxt, zv); return; } ptr = apc_persist_get_already_allocated(ctxt, Z_COUNTED_P(zv)); switch (Z_TYPE_P(zv)) { case IS_STRING: if (!ptr) ptr = apc_persist_copy_zstr(ctxt, Z_STR_P(zv)); ZVAL_STR(zv, ptr); return; case IS_ARRAY: if (!ctxt->serializer) { if (!ptr) ptr = apc_persist_copy_ht(ctxt, Z_ARRVAL_P(zv)); ZVAL_ARR(zv, ptr); return; } /* break missing intentionally */ case IS_OBJECT: apc_persist_copy_serialize(ctxt, zv); return; case IS_REFERENCE: if (!ptr) ptr = apc_persist_copy_ref(ctxt, Z_REF_P(zv)); ZVAL_REF(zv, ptr); return; default: ZEND_ASSERT(0); return; } } static apc_cache_entry_t *apc_persist_copy( apc_persist_context_t *ctxt, const apc_cache_entry_t *orig_entry) { apc_cache_entry_t *entry = COPY(orig_entry, sizeof(apc_cache_entry_t)); entry->key = apc_persist_copy_zstr(ctxt, entry->key); apc_persist_copy_zval(ctxt, &entry->val); return entry; } apc_cache_entry_t *apc_persist( apc_sma_t *sma, apc_serializer_t *serializer, const apc_cache_entry_t *orig_entry) { apc_persist_context_t ctxt; apc_cache_entry_t *entry; apc_persist_init_context(&ctxt, serializer); /* The top-level value should never be a reference */ ZEND_ASSERT(Z_TYPE(orig_entry->val) != IS_REFERENCE); /* If we're serializing an array using the default serializer, we will have * to keep track of potentially repeated refcounted structures. */ if (!serializer && Z_TYPE(orig_entry->val) == IS_ARRAY) { ctxt.memoization_needed = 1; zend_hash_init(&ctxt.already_counted, 0, NULL, NULL, 0); zend_hash_init(&ctxt.already_allocated, 0, NULL, NULL, 0); } if (!apc_persist_calc(&ctxt, orig_entry)) { if (!ctxt.force_serialization) { apc_persist_destroy_context(&ctxt); return NULL; } /* Try again with forced serialization */ apc_persist_destroy_context(&ctxt); apc_persist_init_context(&ctxt, serializer); ctxt.force_serialization = 1; if (!apc_persist_calc(&ctxt, orig_entry)) { apc_persist_destroy_context(&ctxt); return NULL; } } ctxt.alloc = ctxt.alloc_cur = apc_sma_malloc(sma, ctxt.size); if (!ctxt.alloc) { apc_persist_destroy_context(&ctxt); return NULL; } entry = apc_persist_copy(&ctxt, orig_entry); ZEND_ASSERT(ctxt.alloc_cur == ctxt.alloc + ctxt.size); entry->mem_size = ctxt.size; apc_persist_destroy_context(&ctxt); return entry; } /* * UNPERSIST: Copy from SHM to request memory. */ typedef struct _apc_unpersist_context_t { /* Whether we need to memoize already copied refcounteds. */ zend_bool memoization_needed; /* HashTable storing already copied refcounteds. */ HashTable already_copied; } apc_unpersist_context_t; static void apc_unpersist_zval_impl(apc_unpersist_context_t *ctxt, zval *zv); static inline void apc_unpersist_zval(apc_unpersist_context_t *ctxt, zval *zv) { /* No data apart from the zval itself */ if (Z_TYPE_P(zv) < IS_STRING) { return; } apc_unpersist_zval_impl(ctxt, zv); } static zend_bool apc_unpersist_serialized( zval *dst, zend_string *str, apc_serializer_t *serializer) { apc_unserialize_t unserialize = APC_UNSERIALIZER_NAME(php); void *config = NULL; if (serializer) { unserialize = serializer->unserialize; config = serializer->config; } if (unserialize(dst, (unsigned char *) ZSTR_VAL(str), ZSTR_LEN(str), config)) { return 1; } ZVAL_NULL(dst); return 0; } static inline void *apc_unpersist_get_already_copied(apc_unpersist_context_t *ctxt, void *ptr) { if (ctxt->memoization_needed) { return zend_hash_index_find_ptr(&ctxt->already_copied, (uintptr_t) ptr); } return NULL; } static inline void apc_unpersist_add_already_copied( apc_unpersist_context_t *ctxt, const void *old_ptr, void *new_ptr) { if (ctxt->memoization_needed) { zend_hash_index_add_new_ptr(&ctxt->already_copied, (uintptr_t) old_ptr, new_ptr); } } static zend_string *apc_unpersist_zstr(apc_unpersist_context_t *ctxt, const zend_string *orig_str) { zend_string *str = zend_string_init(ZSTR_VAL(orig_str), ZSTR_LEN(orig_str), 0); ZSTR_H(str) = ZSTR_H(orig_str); apc_unpersist_add_already_copied(ctxt, orig_str, str); return str; } static zend_reference *apc_unpersist_ref( apc_unpersist_context_t *ctxt, const zend_reference *orig_ref) { zend_reference *ref = emalloc(sizeof(zend_reference)); apc_unpersist_add_already_copied(ctxt, orig_ref, ref); GC_SET_REFCOUNT(ref, 1); GC_TYPE_INFO(ref) = IS_REFERENCE; #if PHP_VERSION_ID >= 70400 ref->sources.ptr = NULL; #endif ZVAL_COPY_VALUE(&ref->val, &orig_ref->val); apc_unpersist_zval(ctxt, &ref->val); return ref; } static zend_array *apc_unpersist_ht( apc_unpersist_context_t *ctxt, const HashTable *orig_ht) { HashTable *ht = emalloc(sizeof(HashTable)); apc_unpersist_add_already_copied(ctxt, orig_ht, ht); memcpy(ht, orig_ht, sizeof(HashTable)); GC_TYPE_INFO(ht) = GC_ARRAY; if (ht->nNumUsed == 0) { HT_SET_DATA_ADDR(ht, &uninitialized_bucket); return ht; } HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht))); memcpy(HT_GET_DATA_ADDR(ht), HT_GET_DATA_ADDR(orig_ht), HT_HASH_SIZE(ht->nTableMask)); if (ht->u.flags & HASH_FLAG_STATIC_KEYS) { Bucket *p = ht->arData, *q = orig_ht->arData, *p_end = p + ht->nNumUsed; for (; p < p_end; p++, q++) { /* No need to check for UNDEF, as unpersist_zval can be safely called on UNDEF */ *p = *q; apc_unpersist_zval(ctxt, &p->val); } } else { Bucket *p = ht->arData, *q = orig_ht->arData, *p_end = p + ht->nNumUsed; for (; p < p_end; p++, q++) { if (Z_TYPE(q->val) == IS_UNDEF) { ZVAL_UNDEF(&p->val); continue; } p->val = q->val; p->h = q->h; if (q->key) { p->key = zend_string_dup(q->key, 0); } else { p->key = NULL; } apc_unpersist_zval(ctxt, &p->val); } } return ht; } static void apc_unpersist_zval_impl(apc_unpersist_context_t *ctxt, zval *zv) { void *ptr = apc_unpersist_get_already_copied(ctxt, Z_COUNTED_P(zv)); if (ptr) { Z_COUNTED_P(zv) = ptr; Z_ADDREF_P(zv); return; } switch (Z_TYPE_P(zv)) { case IS_STRING: Z_STR_P(zv) = apc_unpersist_zstr(ctxt, Z_STR_P(zv)); return; case IS_REFERENCE: Z_REF_P(zv) = apc_unpersist_ref(ctxt, Z_REF_P(zv)); return; case IS_ARRAY: Z_ARR_P(zv) = apc_unpersist_ht(ctxt, Z_ARR_P(zv)); return; default: ZEND_ASSERT(0); return; } } zend_bool apc_unpersist(zval *dst, const zval *value, apc_serializer_t *serializer) { apc_unpersist_context_t ctxt; if (Z_TYPE_P(value) == IS_PTR) { return apc_unpersist_serialized(dst, Z_PTR_P(value), serializer); } ctxt.memoization_needed = 0; ZEND_ASSERT(Z_TYPE_P(value) != IS_REFERENCE); if (Z_TYPE_P(value) == IS_ARRAY) { ctxt.memoization_needed = 1; zend_hash_init(&ctxt.already_copied, 0, NULL, NULL, 0); } ZVAL_COPY_VALUE(dst, value); apc_unpersist_zval(&ctxt, dst); if (ctxt.memoization_needed) { zend_hash_destroy(&ctxt.already_copied); } return 1; }
Close