|
|
|
@ -144,6 +144,10 @@ static zend_compile_file_t *old_compile_file = NULL; |
|
|
|
|
|
|
|
|
|
static zend_bool xc_readonly_protection = 0; |
|
|
|
|
|
|
|
|
|
static zend_ulong xc_var_namespace_mode = 0; |
|
|
|
|
static char *xc_var_namespace = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
zend_bool xc_have_op_array_ctor = 0; |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
@ -256,7 +260,7 @@ static inline int xc_entry_equal_unlocked(xc_entry_type_t type, const xc_entry_t |
|
|
|
|
|
|
|
|
|
if (entry1->name_type == IS_UNICODE) { |
|
|
|
|
return entry1->name.ustr.len == entry2->name.ustr.len |
|
|
|
|
&& memcmp(entry1->name.ustr.val, entry2->name.ustr.val, (entry1->name.ustr.len + 1) * sizeof(UChar)) == 0; |
|
|
|
|
&& memcmp(entry1->name.ustr.val, entry2->name.ustr.val, (entry1->name.ustr.len + 1) * sizeof(entry1->name.ustr.val[0])) == 0; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
return entry1->name.str.len == entry2->name.str.len |
|
|
|
@ -269,33 +273,6 @@ static inline int xc_entry_equal_unlocked(xc_entry_type_t type, const xc_entry_t |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static inline int xc_entry_has_prefix_unlocked(xc_entry_type_t type, xc_entry_t *entry, zval *prefix) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
/* this function isn't required but can be in unlocked */ |
|
|
|
|
|
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
if (entry->name_type != prefix->type) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (entry->name_type == IS_UNICODE) { |
|
|
|
|
if (entry->name.ustr.len < Z_USTRLEN_P(prefix)) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
return memcmp(entry->name.ustr.val, Z_USTRVAL_P(prefix), Z_USTRLEN_P(prefix) * sizeof(UChar)) == 0; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
if (prefix->type != IS_STRING) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (entry->name.str.len < Z_STRLEN_P(prefix)) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return memcmp(entry->name.str.val, Z_STRVAL_P(prefix), Z_STRLEN_P(prefix)) == 0; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_entry_add_unlocked(xc_cached_t *cached, xc_hash_value_t entryslotid, xc_entry_t *entry) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
xc_entry_t **head = &(cached->entries[entryslotid]); |
|
|
|
@ -2306,6 +2283,308 @@ static void xc_gc_op_array(void *pDest) /* {{{ */ |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* variable namespace */ |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
void xc_var_namespace_init_from_unicodel(const UChar *string, int len TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
if (!len) { |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
ZVAL_EMPTY_UNICODE(&XG(uvar_namespace_hard)); |
|
|
|
|
#endif |
|
|
|
|
ZVAL_EMPTY_STRING(&XG(var_namespace_hard)); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
ZVAL_UNICODE_L(&XG(uvar_namespace_hard), string, len, 1); |
|
|
|
|
/* TODO: copy to var */ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
#endif |
|
|
|
|
void xc_var_namespace_init_from_stringl(const char *string, int len TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
if (!len) { |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
ZVAL_EMPTY_UNICODE(&XG(uvar_namespace_hard)); |
|
|
|
|
#endif |
|
|
|
|
ZVAL_EMPTY_STRING(&XG(var_namespace_hard)); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
ZVAL_STRINGL(&XG(var_namespace_hard), string, len, 1); |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
/* TODO: copy to uvar */ |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
void xc_var_namespace_init_from_long(long value TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
ZVAL_LONG(&XG(var_namespace_hard), value); |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
/* TODO: copy to uvar_namespace */ |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
void xc_var_namespace_set_unicodel(const UChar *unicode, int len TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
zval_dtor(&XG(uvar_namespace_soft)); |
|
|
|
|
zval_dtor(&XG(var_namespace_soft)); |
|
|
|
|
if (len) { |
|
|
|
|
if (!Z_USTRLEN_P(&XG(uvar_namespace_soft))) { |
|
|
|
|
ZVAL_UNICODEL(&XG(uvar_namespace_soft), unicode, len, 1); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
int buffer_len = Z_USTRLEN_P(&XG(var_namespace_hard)) + 1 + len; |
|
|
|
|
char *buffer = emalloc((buffer_len + 1) * sizeof(unicode[0])); |
|
|
|
|
char *p = buffer; |
|
|
|
|
memcpy(p, Z_USTRVAL_P(&XG(var_namespace_hard)), (Z_USTRLEN_P(&XG(var_namespace_hard)) + 1)); |
|
|
|
|
p += (Z_USTRLEN_P(&XG(var_namespace_hard)) + 1) * sizeof(unicode[0]); |
|
|
|
|
memcpy(p, unicode, (len + 1) * sizeof(unicode[0])); |
|
|
|
|
ZVAL_UNICODEL(&XG(uvar_namespace_soft), buffer, buffer_len, 0); |
|
|
|
|
} |
|
|
|
|
/* TODO: copy to var */ |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
XG(uvar_namespace_soft) = XG(uvar_namespace_hard); |
|
|
|
|
zval_copy_ctor(&XG(uvar_namespace_soft)); |
|
|
|
|
#endif |
|
|
|
|
XG(var_namespace_soft) = XG(var_namespace_hard); |
|
|
|
|
zval_copy_ctor(&XG(var_namespace_soft)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
#endif |
|
|
|
|
void xc_var_namespace_set_stringl(const char *string, int len TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
zval_dtor(&XG(uvar_namespace_soft)); |
|
|
|
|
#endif |
|
|
|
|
zval_dtor(&XG(var_namespace_soft)); |
|
|
|
|
if (len) { |
|
|
|
|
if (!Z_STRLEN_P(&XG(var_namespace_soft))) { |
|
|
|
|
ZVAL_STRINGL(&XG(var_namespace_soft), string, len, 1); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
int buffer_len = Z_STRLEN_P(&XG(var_namespace_hard)) + 1 + len; |
|
|
|
|
char *buffer = emalloc(buffer_len + 1); |
|
|
|
|
char *p = buffer; |
|
|
|
|
memcpy(p, Z_STRVAL_P(&XG(var_namespace_hard)), Z_STRLEN_P(&XG(var_namespace_hard)) + 1); |
|
|
|
|
p += Z_STRLEN_P(&XG(var_namespace_hard)) + 1; |
|
|
|
|
memcpy(p, string, len + 1); |
|
|
|
|
ZVAL_STRINGL(&XG(var_namespace_soft), buffer, buffer_len, 0); |
|
|
|
|
} |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
/* TODO: copy to uvar */ |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
XG(uvar_namespace_soft) = XG(uvar_namespace_hard); |
|
|
|
|
zval_copy_ctor(&XG(uvar_namespace_soft)); |
|
|
|
|
#endif |
|
|
|
|
XG(var_namespace_soft) = XG(var_namespace_hard); |
|
|
|
|
zval_copy_ctor(&XG(var_namespace_soft)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_var_namespace_break(TSRMLS_D) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
zval_dtor(&XG(uvar_namespace_soft)); |
|
|
|
|
#endif |
|
|
|
|
zval_dtor(&XG(var_namespace_soft)); |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
ZVAL_EMPTY_UNICODE(&XG(uvar_namespace_soft)); |
|
|
|
|
#endif |
|
|
|
|
ZVAL_EMPTY_STRING(&XG(var_namespace_soft)); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_var_namespace_init(TSRMLS_D) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
uid_t id = (uid_t) -1; |
|
|
|
|
|
|
|
|
|
switch (xc_var_namespace_mode) { |
|
|
|
|
case 1: |
|
|
|
|
{ |
|
|
|
|
zval **server; |
|
|
|
|
HashTable *ht; |
|
|
|
|
zval **val; |
|
|
|
|
|
|
|
|
|
#ifdef ZEND_ENGINE_2_1 |
|
|
|
|
zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void**)&server) == FAILURE |
|
|
|
|
|| Z_TYPE_PP(server) != IS_ARRAY |
|
|
|
|
|| !(ht = Z_ARRVAL_P(*server)) |
|
|
|
|
|| zend_hash_find(ht, xc_var_namespace, strlen(xc_var_namespace) + 1, (void**)&val) == FAILURE) { |
|
|
|
|
xc_var_namespace_init_from_stringl(NULL, 0 TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
if (Z_TYPE_PP(val) == IS_UNICODE) { |
|
|
|
|
xc_var_namespace_init_from_unicodel(Z_USTRVAL_PP(val), Z_USTRLEN_PP(val) TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
xc_var_namespace_init_from_stringl(Z_STRVAL_PP(val), Z_STRLEN_PP(val) TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 2: |
|
|
|
|
if (strncmp(xc_var_namespace, "uid", 3) == 0) { |
|
|
|
|
id = getuid(); |
|
|
|
|
} |
|
|
|
|
else if (strncmp(xc_var_namespace, "gid", 3) == 0) { |
|
|
|
|
id = getgid(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (id == (uid_t) -1){ |
|
|
|
|
xc_var_namespace_init_from_stringl(NULL, 0 TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
xc_var_namespace_init_from_long((long) id TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 0: |
|
|
|
|
default: |
|
|
|
|
xc_var_namespace_init_from_stringl(xc_var_namespace, strlen(xc_var_namespace) TSRMLS_CC); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
INIT_ZVAL(XG(uvar_namespace_soft)); |
|
|
|
|
#endif |
|
|
|
|
INIT_ZVAL(XG(var_namespace_soft)); |
|
|
|
|
xc_var_namespace_set_stringl("", 0 TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_var_namespace_destroy(TSRMLS_D) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
zval_dtor(&XG(uvar_namespace_hard)); |
|
|
|
|
zval_dtor(&XG(uvar_namespace_soft)); |
|
|
|
|
#endif |
|
|
|
|
zval_dtor(&XG(var_namespace_hard)); |
|
|
|
|
zval_dtor(&XG(var_namespace_soft)); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static int xc_var_buffer_prepare(zval *name TSRMLS_DC) /* {{{ prepare name, calculate buffer size */ |
|
|
|
|
{ |
|
|
|
|
int namespace_len; |
|
|
|
|
switch (name->type) { |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
case IS_UNICODE: |
|
|
|
|
do_unicode: |
|
|
|
|
namespace_len = Z_USTRLEN_P(&XG(uvar_namespace_soft)); |
|
|
|
|
return (namespace_len ? namespace_len + 1 : 0) + Z_USTRLEN_P(name); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
case IS_STRING: |
|
|
|
|
do_string: |
|
|
|
|
namespace_len = Z_STRLEN_P(&XG(var_namespace_soft)); |
|
|
|
|
return (namespace_len ? namespace_len + 1 : 0) + Z_STRLEN_P(name); |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
convert_to_unicode(name); |
|
|
|
|
goto do_unicode; |
|
|
|
|
#else |
|
|
|
|
convert_to_string(name); |
|
|
|
|
goto do_string; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static int xc_var_buffer_alloca_size(zval *name TSRMLS_DC) /* {{{ prepare name, calculate buffer size */ |
|
|
|
|
{ |
|
|
|
|
int namespace_len; |
|
|
|
|
switch (name->type) { |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
case IS_UNICODE: |
|
|
|
|
namespace_len = Z_USTRLEN_P(&XG(uvar_namespace_soft)); |
|
|
|
|
return !namespace_len ? 0 : (namespace_len + 1 + Z_USTRLEN_P(name) + 1) * sizeof(Z_USTRVAL_P(&XG(uvar_namespace_soft))[0]); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
case IS_STRING: |
|
|
|
|
namespace_len = Z_STRLEN_P(&XG(var_namespace_soft)); |
|
|
|
|
return !namespace_len ? 0 : (namespace_len + 1 + Z_STRLEN_P(name) + 1); |
|
|
|
|
} |
|
|
|
|
assert(0); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
static void xc_var_buffer_init(char *buffer, zval *name TSRMLS_DC) /* {{{ prepare name, calculate buffer size */ |
|
|
|
|
{ |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
if (Z_TYPE(name) == IS_UNICODE) { |
|
|
|
|
memcpy(buffer, Z_USTRVAL_P(&XG(uvar_namespace_soft)), (Z_USTRLEN_P(&XG(uvar_namespace_soft)) + 1) * sizeof(Z_USTRVAL_P(name)[0])); |
|
|
|
|
buffer += (Z_USTRLEN_P(&XG(uvar_namespace_soft)) + 1) * sizeof(Z_USTRVAL_P(name)[0]); |
|
|
|
|
memcpy(buffer, Z_USTRVAL_P(name), (Z_USTRLEN_P(name) + 1) * sizeof(Z_USTRVAL_P(name)[0])); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
memcpy(buffer, Z_STRVAL_P(&XG(var_namespace_soft)), (Z_STRLEN_P(&XG(var_namespace_soft)) + 1)); |
|
|
|
|
buffer += (Z_STRLEN_P(&XG(var_namespace_soft)) + 1); |
|
|
|
|
memcpy(buffer, Z_STRVAL_P(name), (Z_STRLEN_P(name) + 1)); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
typedef struct xc_namebuffer_t_ { /* {{{ */ |
|
|
|
|
ALLOCA_FLAG(useheap); |
|
|
|
|
void *buffer; |
|
|
|
|
int alloca_size; |
|
|
|
|
int len; |
|
|
|
|
} xc_namebuffer_t; |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
#define VAR_BUFFER_FLAGS(name) \ |
|
|
|
|
xc_namebuffer_t name##_buffer; |
|
|
|
|
|
|
|
|
|
#define VAR_BUFFER_INIT(name) \ |
|
|
|
|
name##_buffer.len = xc_var_buffer_prepare(name TSRMLS_CC); \
|
|
|
|
|
name##_buffer.alloca_size = xc_var_buffer_alloca_size(name TSRMLS_CC); \
|
|
|
|
|
name##_buffer.buffer = name##_buffer.alloca_size \
|
|
|
|
|
? do_alloca(name##_buffer.alloca_size, name##_buffer.useheap) \
|
|
|
|
|
: UNISW(Z_STRVAL_P(name), Z_TYPE(name) == IS_UNICODE ? Z_USTRVAL_P(name) : Z_STRVAL_P(name)); \
|
|
|
|
|
if (name##_buffer.alloca_size) xc_var_buffer_init(name##_buffer.buffer, name TSRMLS_CC); |
|
|
|
|
|
|
|
|
|
#define VAR_BUFFER_FREE(name) \ |
|
|
|
|
if (name##_buffer.alloca_size) { \
|
|
|
|
|
free_alloca(name##_buffer.buffer, name##_buffer.useheap); \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline int xc_var_has_prefix(xc_entry_t *entry, zval *prefix TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
zend_bool result = 0; |
|
|
|
|
VAR_BUFFER_FLAGS(prefix); |
|
|
|
|
|
|
|
|
|
if (UNISW(IS_STRING, entry->name_type) != prefix->type) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
VAR_BUFFER_INIT(prefix); |
|
|
|
|
|
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
if (Z_TYPE(prefix) == IS_UNICODE) { |
|
|
|
|
result = entry->name.ustr.len >= prefix_buffer.len |
|
|
|
|
&& memcmp(entry->name.ustr.val, prefix_buffer.buffer, prefix_buffer.len * sizeof(Z_USTRVAL_P(prefix)[0])) == 0; |
|
|
|
|
goto finish; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
result = entry->name.str.len >= prefix_buffer.len |
|
|
|
|
&& memcmp(entry->name.str.val, prefix_buffer.buffer, prefix_buffer.len) == 0; |
|
|
|
|
goto finish; |
|
|
|
|
|
|
|
|
|
finish: |
|
|
|
|
VAR_BUFFER_FREE(prefix); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
/* module helper function */ |
|
|
|
|
static int xc_init_constant(int module_number TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
@ -2501,7 +2780,7 @@ static void xc_request_init(TSRMLS_D) /* {{{ */ |
|
|
|
|
xc_stack_init(&XG(var_holds[i])); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xc_var_namespace_init(TSRMLS_C); |
|
|
|
|
#ifdef ZEND_ENGINE_2 |
|
|
|
|
zend_llist_init(&XG(gc_op_arrays), sizeof(xc_gc_op_array_t), xc_gc_op_array, 0); |
|
|
|
|
#endif |
|
|
|
@ -2519,6 +2798,7 @@ static void xc_request_shutdown(TSRMLS_D) /* {{{ */ |
|
|
|
|
xc_gc_expires_php(TSRMLS_C); |
|
|
|
|
xc_gc_expires_var(TSRMLS_C); |
|
|
|
|
xc_gc_deletes(TSRMLS_C); |
|
|
|
|
xc_var_namespace_destroy(TSRMLS_C); |
|
|
|
|
#ifdef ZEND_ENGINE_2 |
|
|
|
|
zend_llist_destroy(&XG(gc_op_arrays)); |
|
|
|
|
#endif |
|
|
|
@ -2565,7 +2845,7 @@ static int xcache_admin_auth_check(TSRMLS_D) /* {{{ */ |
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_ERROR, "_SERVER is corrupted"); |
|
|
|
|
zend_bailout(); |
|
|
|
|
} |
|
|
|
|
ht = HASH_OF((*server)); |
|
|
|
|
ht = Z_ARRVAL_P((*server)); |
|
|
|
|
|
|
|
|
|
if (zend_hash_find(ht, "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), (void **) &user) == FAILURE) { |
|
|
|
|
user = NULL; |
|
|
|
@ -2798,32 +3078,28 @@ PHP_FUNCTION(xcache_enable_cache) |
|
|
|
|
xcache_admin_operate(XC_OP_ENABLE, INTERNAL_FUNCTION_PARAM_PASSTHRU); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ proto mixed xcache_admin_namespace()
|
|
|
|
|
Break out of namespace limitation */ |
|
|
|
|
PHP_FUNCTION(xcache_admin_namespace) |
|
|
|
|
{ |
|
|
|
|
xcache_admin_auth_check(TSRMLS_C); |
|
|
|
|
xc_var_namespace_break(TSRMLS_C); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
|
|
|
|
|
#define VAR_CACHE_NOT_INITIALIZED() do { \ |
|
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "XCache var cache was not initialized properly. Check php log for actual reason"); \
|
|
|
|
|
} while (0) |
|
|
|
|
|
|
|
|
|
static int xc_entry_var_init_key(xc_entry_var_t *entry_var, xc_entry_hash_t *entry_hash, zval *name TSRMLS_DC) /* {{{ */ |
|
|
|
|
static int xc_entry_var_init_key(xc_entry_var_t *entry_var, xc_entry_hash_t *entry_hash, xc_namebuffer_t *name_buffer TSRMLS_DC) /* {{{ */ |
|
|
|
|
{ |
|
|
|
|
xc_hash_value_t hv; |
|
|
|
|
|
|
|
|
|
switch (name->type) { |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
case IS_UNICODE: |
|
|
|
|
case IS_STRING: |
|
|
|
|
#endif |
|
|
|
|
default: |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
convert_to_unicode(name); |
|
|
|
|
#else |
|
|
|
|
convert_to_string(name); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
entry_var->name_type = name->type; |
|
|
|
|
#endif |
|
|
|
|
entry_var->entry.name = name->value; |
|
|
|
|
entry_var->entry.name.str.val = name_buffer->buffer; |
|
|
|
|
entry_var->entry.name.str.len = name_buffer->len; |
|
|
|
|
|
|
|
|
|
hv = xc_entry_hash_var((xc_entry_t *) entry_var TSRMLS_CC); |
|
|
|
|
|
|
|
|
@ -2833,6 +3109,31 @@ static int xc_entry_var_init_key(xc_entry_var_t *entry_var, xc_entry_hash_t *ent |
|
|
|
|
return SUCCESS; |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ proto mixed xcache_set_namespace(string namespace)
|
|
|
|
|
Switch to user defined namespace */ |
|
|
|
|
PHP_FUNCTION(xcache_set_namespace) |
|
|
|
|
{ |
|
|
|
|
zval *namespace; |
|
|
|
|
|
|
|
|
|
if (!xc_var_caches) { |
|
|
|
|
VAR_CACHE_NOT_INITIALIZED(); |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &namespace) == FAILURE) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (Z_TYPE_P(namespace) == IS_STRING) { |
|
|
|
|
xc_var_namespace_set_stringl(Z_STRVAL_P(namespace), Z_STRLEN_P(namespace) TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
#ifdef IS_UNICODE |
|
|
|
|
else if (Z_TYPE_P(namespace) == IS_UNICODE) { |
|
|
|
|
xc_var_namespace_set_unicodel(Z_USTRVAL_P(namespace), Z_USTRLEN_P(namespace) TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ proto mixed xcache_get(string name)
|
|
|
|
|
Get cached data by specified name */ |
|
|
|
|
PHP_FUNCTION(xcache_get) |
|
|
|
@ -2841,6 +3142,7 @@ PHP_FUNCTION(xcache_get) |
|
|
|
|
xc_cache_t *cache; |
|
|
|
|
xc_entry_var_t entry_var, *stored_entry_var; |
|
|
|
|
zval *name; |
|
|
|
|
VAR_BUFFER_FLAGS(name); |
|
|
|
|
|
|
|
|
|
if (!xc_var_caches) { |
|
|
|
|
VAR_CACHE_NOT_INITIALIZED(); |
|
|
|
@ -2850,10 +3152,12 @@ PHP_FUNCTION(xcache_get) |
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC); |
|
|
|
|
VAR_BUFFER_INIT(name); |
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC); |
|
|
|
|
cache = &xc_var_caches[entry_hash.cacheid]; |
|
|
|
|
|
|
|
|
|
if (cache->cached->disabled) { |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2868,6 +3172,7 @@ PHP_FUNCTION(xcache_get) |
|
|
|
|
RETVAL_NULL(); |
|
|
|
|
} |
|
|
|
|
} LEAVE_LOCK(cache); |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ proto bool xcache_set(string name, mixed value [, int ttl])
|
|
|
|
@ -2879,6 +3184,7 @@ PHP_FUNCTION(xcache_set) |
|
|
|
|
xc_entry_var_t entry_var, *stored_entry_var; |
|
|
|
|
zval *name; |
|
|
|
|
zval *value; |
|
|
|
|
VAR_BUFFER_FLAGS(name); |
|
|
|
|
|
|
|
|
|
if (!xc_var_caches) { |
|
|
|
|
VAR_CACHE_NOT_INITIALIZED(); |
|
|
|
@ -2900,10 +3206,12 @@ PHP_FUNCTION(xcache_set) |
|
|
|
|
entry_var.entry.ttl = xc_var_maxttl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC); |
|
|
|
|
VAR_BUFFER_INIT(name); |
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC); |
|
|
|
|
cache = &xc_var_caches[entry_hash.cacheid]; |
|
|
|
|
|
|
|
|
|
if (cache->cached->disabled) { |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2915,6 +3223,7 @@ PHP_FUNCTION(xcache_set) |
|
|
|
|
entry_var.value = value; |
|
|
|
|
RETVAL_BOOL(xc_entry_var_store_unlocked(cache, entry_hash.entryslotid, &entry_var TSRMLS_CC) != NULL ? 1 : 0); |
|
|
|
|
} LEAVE_LOCK(cache); |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ proto bool xcache_isset(string name)
|
|
|
|
@ -2925,6 +3234,7 @@ PHP_FUNCTION(xcache_isset) |
|
|
|
|
xc_cache_t *cache; |
|
|
|
|
xc_entry_var_t entry_var, *stored_entry_var; |
|
|
|
|
zval *name; |
|
|
|
|
VAR_BUFFER_FLAGS(name); |
|
|
|
|
|
|
|
|
|
if (!xc_var_caches) { |
|
|
|
|
VAR_CACHE_NOT_INITIALIZED(); |
|
|
|
@ -2934,10 +3244,12 @@ PHP_FUNCTION(xcache_isset) |
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC); |
|
|
|
|
VAR_BUFFER_INIT(name); |
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC); |
|
|
|
|
cache = &xc_var_caches[entry_hash.cacheid]; |
|
|
|
|
|
|
|
|
|
if (cache->cached->disabled) { |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
RETURN_FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2953,6 +3265,7 @@ PHP_FUNCTION(xcache_isset) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} LEAVE_LOCK(cache); |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ proto bool xcache_unset(string name)
|
|
|
|
@ -2963,6 +3276,7 @@ PHP_FUNCTION(xcache_unset) |
|
|
|
|
xc_cache_t *cache; |
|
|
|
|
xc_entry_var_t entry_var, *stored_entry_var; |
|
|
|
|
zval *name; |
|
|
|
|
VAR_BUFFER_FLAGS(name); |
|
|
|
|
|
|
|
|
|
if (!xc_var_caches) { |
|
|
|
|
VAR_CACHE_NOT_INITIALIZED(); |
|
|
|
@ -2972,10 +3286,12 @@ PHP_FUNCTION(xcache_unset) |
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &name) == FAILURE) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC); |
|
|
|
|
VAR_BUFFER_INIT(name); |
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC); |
|
|
|
|
cache = &xc_var_caches[entry_hash.cacheid]; |
|
|
|
|
|
|
|
|
|
if (cache->cached->disabled) { |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
RETURN_FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2989,6 +3305,7 @@ PHP_FUNCTION(xcache_unset) |
|
|
|
|
RETVAL_FALSE; |
|
|
|
|
} |
|
|
|
|
} LEAVE_LOCK(cache); |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ proto bool xcache_unset_by_prefix(string prefix)
|
|
|
|
@ -3019,7 +3336,7 @@ PHP_FUNCTION(xcache_unset_by_prefix) |
|
|
|
|
xc_entry_t *entry, *next; |
|
|
|
|
for (entry = cache->cached->entries[entryslotid]; entry; entry = next) { |
|
|
|
|
next = entry->next; |
|
|
|
|
if (xc_entry_has_prefix_unlocked(XC_TYPE_VAR, entry, prefix)) { |
|
|
|
|
if (xc_var_has_prefix(entry, prefix TSRMLS_CC)) { |
|
|
|
|
xc_entry_remove_unlocked(XC_TYPE_VAR, cache, entryslotid, entry TSRMLS_CC); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -3037,6 +3354,7 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{ |
|
|
|
|
long count = 1; |
|
|
|
|
long value = 0; |
|
|
|
|
zval oldzval; |
|
|
|
|
VAR_BUFFER_FLAGS(name); |
|
|
|
|
|
|
|
|
|
if (!xc_var_caches) { |
|
|
|
|
VAR_CACHE_NOT_INITIALIZED(); |
|
|
|
@ -3053,10 +3371,12 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{ |
|
|
|
|
entry_var.entry.ttl = xc_var_maxttl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, name TSRMLS_CC); |
|
|
|
|
VAR_BUFFER_INIT(name); |
|
|
|
|
xc_entry_var_init_key(&entry_var, &entry_hash, &name_buffer TSRMLS_CC); |
|
|
|
|
cache = &xc_var_caches[entry_hash.cacheid]; |
|
|
|
|
|
|
|
|
|
if (cache->cached->disabled) { |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -3102,6 +3422,7 @@ static inline void xc_var_inc_dec(int inc, INTERNAL_FUNCTION_PARAMETERS) /* {{{ |
|
|
|
|
} |
|
|
|
|
xc_entry_var_store_unlocked(cache, entry_hash.entryslotid, &entry_var TSRMLS_CC); |
|
|
|
|
} LEAVE_LOCK(cache); |
|
|
|
|
VAR_BUFFER_FREE(name); |
|
|
|
|
} |
|
|
|
|
/* }}} */ |
|
|
|
|
/* {{{ proto int xcache_inc(string name [, int value [, int ttl]])
|
|
|
|
@ -3125,6 +3446,8 @@ static zend_function_entry xcache_cacher_functions[] = /* {{{ */ |
|
|
|
|
PHP_FE(xcache_list, NULL) |
|
|
|
|
PHP_FE(xcache_clear_cache, NULL) |
|
|
|
|
PHP_FE(xcache_enable_cache, NULL) |
|
|
|
|
PHP_FE(xcache_admin_namespace, NULL) |
|
|
|
|
PHP_FE(xcache_set_namespace, NULL) |
|
|
|
|
PHP_FE(xcache_get, NULL) |
|
|
|
|
PHP_FE(xcache_set, NULL) |
|
|
|
|
PHP_FE(xcache_isset, NULL) |
|
|
|
@ -3220,6 +3543,8 @@ PHP_INI_BEGIN() |
|
|
|
|
PHP_INI_ENTRY1 ("xcache.var_gc_interval", "120", PHP_INI_SYSTEM, xcache_OnUpdateULong, &xc_var_gc_interval) |
|
|
|
|
PHP_INI_ENTRY1 ("xcache.var_allocator", "bestfit", PHP_INI_SYSTEM, xcache_OnUpdateString, &xc_var_allocator) |
|
|
|
|
STD_PHP_INI_ENTRY ("xcache.var_ttl", "0", PHP_INI_ALL, OnUpdateLong, var_ttl, zend_xcache_globals, xcache_globals) |
|
|
|
|
PHP_INI_ENTRY1 ("xcache.var_namespace_mode", "0", PHP_INI_SYSTEM, xcache_OnUpdateULong, &xc_var_namespace_mode) |
|
|
|
|
PHP_INI_ENTRY1 ("xcache.var_namespace", "", PHP_INI_SYSTEM, xcache_OnUpdateString, &xc_var_namespace) |
|
|
|
|
PHP_INI_END() |
|
|
|
|
/* }}} */ |
|
|
|
|
static PHP_MINFO_FUNCTION(xcache_cacher) /* {{{ */ |
|
|
|
@ -3394,6 +3719,10 @@ static PHP_MSHUTDOWN_FUNCTION(xcache_cacher) /* {{{ */ |
|
|
|
|
pefree(xc_var_allocator, 1); |
|
|
|
|
xc_var_allocator = NULL; |
|
|
|
|
} |
|
|
|
|
if (xc_var_namespace) { |
|
|
|
|
pefree(xc_var_namespace, 1); |
|
|
|
|
xc_var_namespace = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return SUCCESS; |
|
|
|
|
} |
|
|
|
|