Added concept of interned strings. All strings constants known at compile time are allocated in a single copy and never changed.

This commit is contained in:
Dmitry Stogov 2010-04-20 11:05:54 +00:00
parent 94dd83722b
commit dd5c478be6
30 changed files with 838 additions and 192 deletions

2
NEWS
View File

@ -4,6 +4,8 @@
- Upgraded bundled sqlite to version 3.6.23.1. (Ilia)
- Upgraded bundled PCRE to version 8.02. (Ilia)
- Added concept of interned strings. All strings constants known at compile
time are allocated in a single copy and never changed. (Dmitry)
- Added an optimization which saves memory and emalloc/efree calls for empty
HashTables (Stas, Dmitry)
- Added Tokyo Cabinet abstract DB support to ext/dba. (Michael Maclean)

View File

@ -17,7 +17,7 @@ libZend_la_SOURCES=\
zend_objects_API.c zend_ts_hash.c zend_stream.c \
zend_default_classes.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c \
zend_strtod.c zend_closures.c zend_float.c
zend_strtod.c zend_closures.c zend_float.c zend_string.c
libZend_la_LDFLAGS =
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@

View File

@ -243,6 +243,10 @@ SOURCE=.\zend_stream.c
# End Source File
# Begin Source File
SOURCE=.\zend_string.c
# End Source File
# Begin Source File
SOURCE=.\zend_strtod.c
# End Source File
# Begin Source File
@ -411,6 +415,10 @@ SOURCE=.\zend_stream.h
# End Source File
# Begin Source File
SOURCE=.\zend_string.h
# End Source File
# Begin Source File
SOURCE=.\zend_strtod.h
# End Source File
# Begin Source File

View File

@ -273,6 +273,10 @@ SOURCE=.\zend_stream.c
# End Source File
# Begin Source File
SOURCE=.\zend_string.c
# End Source File
# Begin Source File
SOURCE=.\zend_strtod.c
# End Source File
# Begin Source File
@ -445,6 +449,10 @@ SOURCE=.\zend_stream.h
# End Source File
# Begin Source File
SOURCE=.\zend_string.h
# End Source File
# Begin Source File
SOURCE=.\zend_strtod.h
# End Source File
# Begin Source File

View File

@ -693,6 +693,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
EG(user_exception_handler) = NULL;
#endif
zend_interned_strings_init(TSRMLS_C);
zend_startup_builtin_functions(TSRMLS_C);
zend_register_standard_constants(TSRMLS_C);
zend_register_auto_global("GLOBALS", sizeof("GLOBALS") - 1, NULL TSRMLS_CC);
@ -781,6 +782,8 @@ void zend_shutdown(TSRMLS_D) /* {{{ */
GLOBAL_CONSTANTS_TABLE = NULL;
#endif
zend_destroy_rsrc_list_dtors();
zend_interned_strings_dtor(TSRMLS_C);
}
/* }}} */

View File

@ -237,6 +237,7 @@ char *alloca ();
#include "zend_alloc.h"
#include "zend_types.h"
#include "zend_string.h"
#ifdef HAVE_LIMITS_H
# include <limits.h>
@ -599,8 +600,8 @@ END_EXTERN_C()
/* FIXME: Check if we can save if (ptr) too */
#define STR_FREE(ptr) if (ptr) { efree(ptr); }
#define STR_FREE_REL(ptr) if (ptr) { efree_rel(ptr); }
#define STR_FREE(ptr) if (ptr && !IS_INTERNED(ptr)) { efree(ptr); }
#define STR_FREE_REL(ptr) if (ptr && !IS_INTERNED(ptr)) { efree_rel(ptr); }
#define STR_EMPTY_ALLOC() estrndup("", sizeof("")-1)

View File

@ -1893,10 +1893,10 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
}
}
fname_len = strlen(ptr->fname);
lowercase_name = zend_str_tolower_dup(ptr->fname, fname_len);
lowercase_name = CG(new_interned_string)(zend_str_tolower_dup(ptr->fname, fname_len), fname_len + 1, 1 TSRMLS_CC);
if (zend_hash_add(target_function_table, lowercase_name, fname_len+1, &function, sizeof(zend_function), (void**)&reg_function) == FAILURE) {
unload=1;
efree(lowercase_name);
str_efree(lowercase_name);
break;
}
if (scope) {
@ -1938,7 +1938,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
}
ptr++;
count++;
efree(lowercase_name);
str_efree(lowercase_name);
}
if (unload) { /* before unloading, display all remaining bad function in the module */
if (scope) {
@ -2168,7 +2168,7 @@ int zend_next_free_module(void) /* {{{ */
static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, zend_uint ce_flags TSRMLS_DC) /* {{{ */
{
zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
char *lowercase_name = malloc(orig_class_entry->name_length + 1);
char *lowercase_name = emalloc(orig_class_entry->name_length + 1);
*class_entry = *orig_class_entry;
class_entry->type = ZEND_INTERNAL_CLASS;
@ -2181,8 +2181,9 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
}
zend_str_tolower_copy(lowercase_name, orig_class_entry->name, class_entry->name_length);
lowercase_name = CG(new_interned_string)(lowercase_name, class_entry->name_length + 1, 1 TSRMLS_CC);
zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, &class_entry, sizeof(zend_class_entry *), NULL);
free(lowercase_name);
str_efree(lowercase_name);
return class_entry;
}
/* }}} */
@ -3070,6 +3071,7 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, const char *name, in
{
zend_property_info property_info;
HashTable *target_symbol_table;
char *interned_name;
if (!(access_type & ZEND_ACC_PPP_MASK)) {
access_type |= ZEND_ACC_PUBLIC;
@ -3097,7 +3099,6 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, const char *name, in
int priv_name_length;
zend_mangle_property_name(&priv_name, &priv_name_length, ce->name, ce->name_length, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
zend_hash_update(target_symbol_table, priv_name, priv_name_length+1, &property, sizeof(zval *), NULL);
property_info.name = priv_name;
property_info.name_length = priv_name_length;
}
@ -3107,7 +3108,6 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, const char *name, in
int prot_name_length;
zend_mangle_property_name(&prot_name, &prot_name_length, "*", 1, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
zend_hash_update(target_symbol_table, prot_name, prot_name_length+1, &property, sizeof(zval *), NULL);
property_info.name = prot_name;
property_info.name_length = prot_name_length;
}
@ -3121,11 +3121,27 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, const char *name, in
zend_hash_del(target_symbol_table, prot_name, prot_name_length+1);
pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS);
}
zend_hash_update(target_symbol_table, name, name_length+1, &property, sizeof(zval *), NULL);
property_info.name = ce->type & ZEND_INTERNAL_CLASS ? zend_strndup(name, name_length) : estrndup(name, name_length);
if (IS_INTERNED(name)) {
property_info.name = (char*)name;
} else {
property_info.name = ce->type & ZEND_INTERNAL_CLASS ? zend_strndup(name, name_length) : estrndup(name, name_length);
}
property_info.name_length = name_length;
break;
}
interned_name = CG(new_interned_string)(property_info.name, property_info.name_length+1, 0 TSRMLS_CC);
if (interned_name != property_info.name) {
if (ce->type == ZEND_USER_CLASS) {
efree(property_info.name);
} else {
free(property_info.name);
}
property_info.name = interned_name;
}
zend_hash_update(target_symbol_table, property_info.name, property_info.name_length+1, &property, sizeof(zval *), NULL);
property_info.flags = access_type;
property_info.h = zend_get_hash_value(property_info.name, property_info.name_length+1);

View File

@ -681,7 +681,7 @@ repeat:
zval_ptr_dtor(&val_free);
}
c.flags = case_sensitive; /* non persistent */
c.name = zend_strndup(name, name_len);
c.name = IS_INTERNED(name) ? name : zend_strndup(name, name_len);
c.name_len = name_len+1;
c.module_number = PHP_USER_CONSTANT;
if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {

View File

@ -73,7 +73,9 @@ ZEND_API zend_executor_globals executor_globals;
static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */
{
property_info->name = estrndup(property_info->name, property_info->name_length);
if (!IS_INTERNED(property_info->name)) {
property_info->name = estrndup(property_info->name, property_info->name_length);
}
if (property_info->doc_comment) {
property_info->doc_comment = estrndup(property_info->doc_comment, property_info->doc_comment_len);
}
@ -83,14 +85,16 @@ static void zend_duplicate_property_info(zend_property_info *property_info) /* {
static void zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */
{
property_info->name = zend_strndup(property_info->name, property_info->name_length);
if (!IS_INTERNED(property_info->name)) {
property_info->name = zend_strndup(property_info->name, property_info->name_length);
}
}
/* }}} */
static void zend_destroy_property_info(zend_property_info *property_info) /* {{{ */
{
efree(property_info->name);
str_efree(property_info->name);
if (property_info->doc_comment) {
efree(property_info->doc_comment);
}
@ -100,7 +104,7 @@ static void zend_destroy_property_info(zend_property_info *property_info) /* {{{
static void zend_destroy_property_info_internal(zend_property_info *property_info) /* {{{ */
{
free(property_info->name);
str_free(property_info->name);
}
/* }}} */
@ -292,17 +296,18 @@ static zend_uint get_temporary_variable(zend_op_array *op_array) /* {{{ */
}
/* }}} */
static int lookup_cv(zend_op_array *op_array, char* name, int name_len) /* {{{ */
static int lookup_cv(zend_op_array *op_array, char* name, int name_len TSRMLS_DC) /* {{{ */
{
int i = 0;
ulong hash_value = zend_inline_hash_func(name, name_len+1);
while (i < op_array->last_var) {
if (op_array->vars[i].hash_value == hash_value &&
op_array->vars[i].name_len == name_len &&
strcmp(op_array->vars[i].name, name) == 0) {
efree(name);
return i;
if (op_array->vars[i].name == name ||
(op_array->vars[i].hash_value == hash_value &&
op_array->vars[i].name_len == name_len &&
memcmp(op_array->vars[i].name, name, name_len) == 0)) {
str_efree(name);
return i;
}
i++;
}
@ -312,7 +317,7 @@ static int lookup_cv(zend_op_array *op_array, char* name, int name_len) /* {{{ *
op_array->size_var += 16; /* FIXME */
op_array->vars = erealloc(op_array->vars, op_array->size_var*sizeof(zend_compiled_variable));
}
op_array->vars[i].name = name; /* estrndup(name, name_len); */
op_array->vars[i].name = CG(new_interned_string)(name, name_len + 1, 1 TSRMLS_CC);
op_array->vars[i].name_len = name_len;
op_array->vars[i].hash_value = hash_value;
return i;
@ -338,6 +343,13 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv) /* {{{ */
op_array->size_literal += 16; /* FIXME */
op_array->literals = (zend_literal*)erealloc(op_array->literals, op_array->size_literal * sizeof(zend_literal));
}
if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) {
zval *z = (zval*)zv;
TSRMLS_FETCH();
Z_STRVAL_P(z) =
CG(new_interned_string)(Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1, 1 TSRMLS_CC);
}
CONSTANT_EX(op_array, i) = *zv;
Z_SET_REFCOUNT(CONSTANT_EX(op_array, i), 2);
Z_SET_ISREF(CONSTANT_EX(op_array, i));
@ -463,7 +475,8 @@ void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar
(CG(active_op_array)->last == 0 ||
CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE)) {
result->op_type = IS_CV;
result->u.op.var = lookup_cv(CG(active_op_array), varname->u.constant.value.str.val, varname->u.constant.value.str.len);
result->u.op.var = lookup_cv(CG(active_op_array), varname->u.constant.value.str.val, varname->u.constant.value.str.len TSRMLS_CC);
varname->u.constant.value.str.val = CG(active_op_array)->vars[result->u.op.var].name;
result->EA = 0;
return;
}
@ -1078,7 +1091,7 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS
this_var = opline_ptr->result.var;
if (CG(active_op_array)->this_var == -1) {
CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), Z_STRVAL(CONSTANT(opline_ptr->op1.constant)), Z_STRLEN(CONSTANT(opline_ptr->op1.constant)));
CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), Z_STRVAL(CONSTANT(opline_ptr->op1.constant)), Z_STRLEN(CONSTANT(opline_ptr->op1.constant)) TSRMLS_CC);
Z_TYPE(CONSTANT(opline_ptr->op1.constant)) = IS_NULL;
} else {
zend_del_literal(CG(active_op_array), opline_ptr->op1.constant);
@ -1090,7 +1103,7 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS
variable->u.op.var = CG(active_op_array)->this_var;
}
} else if (CG(active_op_array)->this_var == -1) {
CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), estrndup("this", sizeof("this")-1), sizeof("this")-1);
CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), estrndup("this", sizeof("this")-1), sizeof("this")-1 TSRMLS_CC);
}
}
@ -1290,7 +1303,6 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
}
function_token->u.op_array = CG(active_op_array);
lcname = zend_str_tolower_dup(name, name_len);
orig_interactive = CG(interactive);
CG(interactive) = 0;
@ -1308,6 +1320,8 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
if (is_method) {
lcname = CG(new_interned_string)(zend_str_tolower_dup(name, name_len), name_len + 1, 1 TSRMLS_CC);
if (zend_hash_add(&CG(active_class_entry)->function_table, lcname, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name);
}
@ -1413,7 +1427,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
free_alloca(class_lcname, use_heap);
}
efree(lcname);
str_efree(lcname);
} else {
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
zval key;
@ -1426,9 +1440,10 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
zval_copy_ctor(&tmp.u.constant);
zend_do_build_namespace_name(&tmp, &tmp, function_name TSRMLS_CC);
op_array.function_name = Z_STRVAL(tmp.u.constant);
efree(lcname);
name_len = Z_STRLEN(tmp.u.constant);
lcname = zend_str_tolower_dup(Z_STRVAL(tmp.u.constant), name_len);
} else {
lcname = zend_str_tolower_dup(name, name_len);
}
opline->opcode = ZEND_DECLARE_FUNCTION;
@ -1596,7 +1611,7 @@ void zend_do_receive_arg(zend_uchar op, const znode *var, const znode *offset, c
}
CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
cur_arg_info->name = estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len);
cur_arg_info->name = CG(new_interned_string)(estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len), varname->u.constant.value.str.len + 1, 1 TSRMLS_CC);
cur_arg_info->name_len = varname->u.constant.value.str.len;
cur_arg_info->array_type_hint = 0;
cur_arg_info->allow_null = 1;
@ -1610,6 +1625,7 @@ void zend_do_receive_arg(zend_uchar op, const znode *var, const znode *offset, c
if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) {
zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC);
}
class_type->u.constant.value.str.val = CG(new_interned_string)(class_type->u.constant.value.str.val, class_type->u.constant.value.str.len + 1, 1 TSRMLS_CC);
cur_arg_info->class_name = class_type->u.constant.value.str.val;
cur_arg_info->class_name_len = class_type->u.constant.value.str.len;
if (op == ZEND_RECV_INIT) {
@ -1683,7 +1699,7 @@ zend_error(E_ERROR, "Internal error 1 ???");
lc_name = zend_str_tolower_dup(Z_STRVAL(CONSTANT(literal)), Z_STRLEN(CONSTANT(literal)));
ZVAL_STRINGL(&c, lc_name, Z_STRLEN(CONSTANT(literal)), 0);
lc_literal = zend_add_literal(CG(active_op_array), &c);
Z_HASH_P(&CONSTANT(lc_literal)) = zend_hash_func(lc_name, Z_STRLEN(CONSTANT(literal))+1);
Z_HASH_P(&CONSTANT(lc_literal)) = zend_hash_func(Z_STRVAL(c), Z_STRLEN(c)+1);
if (literal + 1 != lc_literal) {
zend_error(E_ERROR, "Internal error 2 ???");
}
@ -1710,7 +1726,7 @@ zend_error(E_ERROR, "Internal error 3 ???");
}
ZVAL_STRINGL(&c, lc_name, lc_len, 0);
lc_literal = zend_add_literal(CG(active_op_array), &c);
Z_HASH_P(&CONSTANT(lc_literal)) = zend_hash_func(lc_name, lc_len+1);
Z_HASH_P(&CONSTANT(lc_literal)) = zend_hash_func(Z_STRVAL(c), Z_STRLEN(c)+1);
if (literal + 1 != lc_literal) {
zend_error(E_ERROR, "Internal error 4 ???");
}
@ -2476,7 +2492,7 @@ void zend_do_try(znode *try_token TSRMLS_DC) /* {{{ */
}
/* }}} */
void zend_do_begin_catch(znode *try_token, znode *class_name, const znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */
void zend_do_begin_catch(znode *try_token, znode *class_name, znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */
{
long catch_op_number;
zend_op *opline;
@ -2500,7 +2516,8 @@ void zend_do_begin_catch(znode *try_token, znode *class_name, const znode *catch
opline->opcode = ZEND_CATCH;
SET_NODE(opline->op1, &catch_class);
opline->op2_type = IS_CV;
opline->op2.var = lookup_cv(CG(active_op_array), catch_var->u.constant.value.str.val, catch_var->u.constant.value.str.len);
opline->op2.var = lookup_cv(CG(active_op_array), catch_var->u.constant.value.str.val, catch_var->u.constant.value.str.len TSRMLS_CC);
catch_var->u.constant.value.str.val = CG(active_op_array)->vars[opline->op2.var].name;
opline->result.num = 0; /* 1 means it's the last catch in the block */
try_token->u.op.opline_num = catch_op_number;
@ -3806,7 +3823,7 @@ void zend_do_declare_property(const znode *var_name, const znode *value, zend_ui
CG(doc_comment_len) = 0;
}
zend_declare_property_ex(CG(active_class_entry), var_name->u.constant.value.str.val, var_name->u.constant.value.str.len, property, access_type, comment, comment_len TSRMLS_CC);
zend_declare_property_ex(CG(active_class_entry), CG(new_interned_string)(var_name->u.constant.value.str.val, var_name->u.constant.value.str.len + 1, 0 TSRMLS_CC), var_name->u.constant.value.str.len, property, access_type, comment, comment_len TSRMLS_CC);
efree(var_name->u.constant.value.str.val);
}
/* }}} */
@ -3822,7 +3839,7 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D
ALLOC_ZVAL(property);
*property = value->u.constant;
if (zend_hash_add(&CG(active_class_entry)->constants_table, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL)==FAILURE) {
if (zend_hash_add(&CG(active_class_entry)->constants_table, CG(new_interned_string)(var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, 0 TSRMLS_CC), var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL)==FAILURE) {
FREE_ZVAL(property);
zend_error(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val);
}

View File

@ -456,7 +456,7 @@ void zend_do_begin_lambda_function_declaration(znode *result, znode *function_to
void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC);
void zend_do_try(znode *try_token TSRMLS_DC);
void zend_do_begin_catch(znode *try_token, znode *catch_class, const znode *catch_var, znode *first_catch TSRMLS_DC);
void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, znode *first_catch TSRMLS_DC);
void zend_do_end_catch(const znode *try_token TSRMLS_DC);
void zend_do_throw(const znode *expr TSRMLS_DC);

View File

@ -32,13 +32,15 @@ void free_zend_constant(zend_constant *c)
if (!(c->flags & CONST_PERSISTENT)) {
zval_dtor(&c->value);
}
free(c->name);
str_free(c->name);
}
void copy_zend_constant(zend_constant *c)
{
c->name = zend_strndup(c->name, c->name_len - 1);
if (!IS_INTERNED(c->name)) {
c->name = zend_strndup(c->name, c->name_len - 1);
}
if (!(c->flags & CONST_PERSISTENT)) {
zval_copy_ctor(&c->value);
}
@ -422,12 +424,14 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
/* keep in mind that c->name_len already contains the '\0' */
lowercase_name = estrndup(c->name, c->name_len-1);
zend_str_tolower(lowercase_name, c->name_len-1);
lowercase_name = CG(new_interned_string)(lowercase_name, c->name_len, 1 TSRMLS_CC);
name = lowercase_name;
} else {
char *slash = strrchr(c->name, '\\');
if(slash) {
lowercase_name = estrndup(c->name, c->name_len-1);
zend_str_tolower(lowercase_name, slash-c->name);
lowercase_name = CG(new_interned_string)(lowercase_name, c->name_len, 1 TSRMLS_CC);
name = lowercase_name;
} else {
name = c->name;
@ -437,13 +441,13 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
if ((strncmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1) == 0) ||
zend_hash_add(EG(zend_constants), name, c->name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
zend_error(E_NOTICE,"Constant %s already defined", name);
free(c->name);
str_free(c->name);
if (!(c->flags & CONST_PERSISTENT)) {
zval_dtor(&c->value);
}
ret = FAILURE;
}
if (lowercase_name) {
if (lowercase_name && !IS_INTERNED(lowercase_name)) {
efree(lowercase_name);
}
return ret;

View File

@ -610,12 +610,24 @@ static inline int zend_assign_to_string_offset(const temp_variable *T, const zva
}
if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) {
char *tmp = (char *) emalloc(T->str_offset.offset+1+1);
memcpy(tmp, Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
Z_STRVAL_P(T->str_offset.str) = tmp;
} else {
Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
}
memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str),
' ',
T->str_offset.offset - Z_STRLEN_P(T->str_offset.str));
Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0;
Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1;
} else if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) {
char *tmp = (char *) emalloc(Z_STRLEN_P(T->str_offset.str) + 1);
memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str) + 1);
Z_STRVAL_P(T->str_offset.str) = tmp;
}
if (Z_TYPE_P(value) != IS_STRING) {
@ -803,7 +815,11 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zva
hval = Z_HASH_P(dim);
} else {
ZEND_HANDLE_NUMERIC_EX(offset_key, offset_key_length+1, index, goto num_index);
hval = zend_hash_func(offset_key, offset_key_length+1);
if (IS_INTERNED(offset_key)) {
hval = INTERNED_HASH(offset_key);
} else {
hval = zend_hash_func(offset_key, offset_key_length+1);
}
}
fetch_string_dim:
if (zend_hash_quick_find(ht, offset_key, offset_key_length+1, hval, (void **) &retval) == FAILURE) {

View File

@ -525,7 +525,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1);
if (inline_change) {
colon = estrndup(colon, Z_STRLEN_P(p));
efree(Z_STRVAL_P(p));
str_efree(Z_STRVAL_P(p));
Z_STRVAL_P(p) = colon;
} else {
Z_STRVAL_P(p) = colon + 1;
@ -561,12 +561,12 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
if (fix_save) {
save--;
}
if (inline_change) {
if (inline_change && !IS_INTERNED(save)) {
efree(save);
}
save = NULL;
}
if (inline_change && save && save != actual) {
if (inline_change && save && save != actual && !IS_INTERNED(save)) {
efree(save);
}
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);

View File

@ -140,6 +140,18 @@ struct _zend_compiler_globals {
HashTable *labels;
zend_stack labels_stack;
/* interned strings */
char *interned_strings_start;
char *interned_strings_end;
char *interned_strings_top;
char *interned_strings_snapshot_top;
HashTable interned_strings;
char *(*new_interned_string)(char *str, int len, int free_src TSRMLS_DC);
void (*interned_strings_snapshot)(TSRMLS_D);
void (*interned_strings_restore)(TSRMLS_D);
#ifdef ZEND_MULTIBYTE
zend_encoding **script_encoding_list;
size_t script_encoding_list_size;

View File

@ -20,6 +20,7 @@
/* $Id$ */
#include "zend.h"
#include "zend_globals.h"
#define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
(element)->pNext = (list_head); \
@ -210,8 +211,8 @@ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKe
p = ht->arBuckets[nIndex];
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (p->arKey == arKey ||
((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) {
if (flag & HASH_ADD) {
return FAILURE;
}
@ -232,16 +233,24 @@ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKe
}
HANDLE_UNBLOCK_INTERRUPTIONS();
return SUCCESS;
}
}
p = p->pNext;
}
p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent);
if (!p) {
return FAILURE;
if (IS_INTERNED(arKey)) {
p = (Bucket *) pemalloc(sizeof(Bucket), ht->persistent);
if (!p) {
return FAILURE;
}
p->arKey = (char*)arKey;
} else {
p = (Bucket *) pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent);
if (!p) {
return FAILURE;
}
p->arKey = (char*)(p + 1);
memcpy(p->arKey, arKey, nKeyLength);
}
memcpy(p->arKey, arKey, nKeyLength);
p->nKeyLength = nKeyLength;
INIT_DATA(ht, p, pData, nDataSize);
p->h = h;
@ -276,8 +285,8 @@ ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, ui
p = ht->arBuckets[nIndex];
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (p->arKey == arKey ||
((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) {
if (flag & HASH_ADD) {
return FAILURE;
}
@ -298,17 +307,25 @@ ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, ui
}
HANDLE_UNBLOCK_INTERRUPTIONS();
return SUCCESS;
}
}
p = p->pNext;
}
p = (Bucket *) pemalloc(sizeof(Bucket) - 1 + nKeyLength, ht->persistent);
if (!p) {
return FAILURE;
if (IS_INTERNED(arKey)) {
p = (Bucket *) pemalloc(sizeof(Bucket), ht->persistent);
if (!p) {
return FAILURE;
}
p->arKey = (char*)arKey;
} else {
p = (Bucket *) pemalloc(sizeof(Bucket) + nKeyLength, ht->persistent);
if (!p) {
return FAILURE;
}
p->arKey = (char*)(p + 1);
memcpy(p->arKey, arKey, nKeyLength);
}
memcpy(p->arKey, arKey, nKeyLength);
p->nKeyLength = nKeyLength;
INIT_DATA(ht, p, pData, nDataSize);
p->h = h;
@ -380,10 +397,11 @@ ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void
}
p = p->pNext;
}
p = (Bucket *) pemalloc_rel(sizeof(Bucket) - 1, ht->persistent);
p = (Bucket *) pemalloc_rel(sizeof(Bucket), ht->persistent);
if (!p) {
return FAILURE;
}
p->arKey = NULL;
p->nKeyLength = 0; /* Numeric indices are marked by making the nKeyLength == 0 */
p->h = h;
INIT_DATA(ht, p, pData, nDataSize);
@ -885,11 +903,10 @@ ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLen
p = ht->arBuckets[nIndex];
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (p->arKey == arKey ||
((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) {
*pData = p->pData;
return SUCCESS;
}
}
p = p->pNext;
}
@ -912,11 +929,10 @@ ZEND_API int zend_hash_quick_find(const HashTable *ht, const char *arKey, uint n
p = ht->arBuckets[nIndex];
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (p->arKey == arKey ||
((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) {
*pData = p->pData;
return SUCCESS;
}
}
p = p->pNext;
}
@ -937,10 +953,9 @@ ZEND_API int zend_hash_exists(const HashTable *ht, const char *arKey, uint nKeyL
p = ht->arBuckets[nIndex];
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (p->arKey == arKey ||
((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) {
return 1;
}
}
p = p->pNext;
}
@ -963,10 +978,9 @@ ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint
p = ht->arBuckets[nIndex];
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (p->arKey == arKey ||
((p->h == h) && (p->nKeyLength == nKeyLength) && !memcmp(p->arKey, arKey, nKeyLength))) {
return 1;
}
}
p = p->pNext;
}
@ -1290,7 +1304,7 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const
}
if (p->nKeyLength != str_length) {
Bucket *q = (Bucket *) pemalloc(sizeof(Bucket) - 1 + str_length, ht->persistent);
Bucket *q = (Bucket *) pemalloc(sizeof(Bucket) + str_length, ht->persistent);
q->nKeyLength = str_length;
if (p->pData == &p->pDataPtr) {
@ -1324,6 +1338,7 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const
if (key_type == HASH_KEY_IS_LONG) {
p->h = num_index;
} else {
p->arKey = (char*)(p+1);
memcpy(p->arKey, str_index, str_length);
p->h = zend_inline_hash_func(str_index, str_length);
}

View File

@ -60,7 +60,7 @@ typedef struct bucket {
struct bucket *pListLast;
struct bucket *pNext;
struct bucket *pLast;
char arKey[1]; /* Must be last element */
char *arKey;
} Bucket;
typedef struct _hashtable {

View File

@ -408,7 +408,13 @@ zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC)
ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_DC)
{
/* enforce two trailing NULLs for flex... */
str->value.str.val = safe_erealloc(str->value.str.val, 1, str->value.str.len, ZEND_MMAP_AHEAD);
if (IS_INTERNED(str->value.str.val)) {
char *tmp = safe_emalloc(1, str->value.str.len, ZEND_MMAP_AHEAD);
memcpy(tmp, str->value.str.val, str->value.str.len + ZEND_MMAP_AHEAD);
str->value.str.val = tmp;
} else {
str->value.str.val = safe_erealloc(str->value.str.val, 1, str->value.str.len, ZEND_MMAP_AHEAD);
}
memset(str->value.str.val + str->value.str.len, 0, ZEND_MMAP_AHEAD);

View File

@ -243,7 +243,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
i = op_array->last_var;
while (i > 0) {
i--;
efree(op_array->vars[i].name);
str_efree(op_array->vars[i].name);
}
efree(op_array->vars);
}
@ -275,8 +275,8 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
}
if (op_array->arg_info) {
for (i=0; i<op_array->num_args; i++) {
efree((char*)op_array->arg_info[i].name);
if (op_array->arg_info[i].class_name) {
str_efree((char*)op_array->arg_info[i].name);
if (op_array->arg_info[i].class_name && !IS_INTERNED(op_array->arg_info[i].class_name)) {
efree((char*)op_array->arg_info[i].class_name);
}
}

View File

@ -1177,11 +1177,18 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
/* must support result==op1 */
ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
{
Z_STRLEN_P(result) = Z_STRLEN_P(op1) + 1;
Z_STRVAL_P(result) = (char *) erealloc(Z_STRVAL_P(op1), Z_STRLEN_P(result)+1);
Z_STRVAL_P(result)[Z_STRLEN_P(result) - 1] = (char) Z_LVAL_P(op2);
Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
Z_TYPE_P(result) = IS_STRING;
int length = Z_STRLEN_P(op1) + 1;
char *buf;
if (IS_INTERNED(Z_STRVAL_P(op1))) {
buf = (char *) emalloc(length + 1);
memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
} else {
buf = (char *) erealloc(Z_STRVAL_P(op1), length + 1);
}
buf[length - 1] = (char) Z_LVAL_P(op2);
buf[length] = 0;
ZVAL_STRINGL(result, buf, length, 0);
return SUCCESS;
}
/* }}} */
@ -1190,12 +1197,17 @@ ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2)
ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
{
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
char *buf;
Z_STRVAL_P(result) = (char *) erealloc(Z_STRVAL_P(op1), length+1);
memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
Z_STRVAL_P(result)[length] = 0;
Z_STRLEN_P(result) = length;
Z_TYPE_P(result) = IS_STRING;
if (IS_INTERNED(Z_STRVAL_P(op1))) {
buf = (char *) emalloc(length+1);
memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
} else {
buf = (char *) erealloc(Z_STRVAL_P(op1), length+1);
}
memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
buf[length] = 0;
ZVAL_STRINGL(result, buf, length, 0);
return SUCCESS;
}
/* }}} */
@ -1224,7 +1236,7 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
if (use_copy2) {
op2 = &op2_copy;
}
if (result==op1) { /* special case, perform operations on result */
if (result==op1 && !IS_INTERNED(Z_STRVAL_P(op1))) { /* special case, perform operations on result */
uint res_len = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
if (Z_STRLEN_P(result) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
@ -1239,12 +1251,13 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
Z_STRVAL_P(result)[res_len]=0;
Z_STRLEN_P(result) = res_len;
} else {
Z_STRLEN_P(result) = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
Z_TYPE_P(result) = IS_STRING;
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
char *buf = (char *) emalloc(length + 1);
memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
buf[length] = 0;
ZVAL_STRINGL(result, buf, length, 0);
}
if (use_copy1) {
zval_dtor(op1);
@ -1668,6 +1681,12 @@ static void increment_string(zval *str) /* {{{ */
return;
}
if (IS_INTERNED(s)) {
s = (char*) emalloc(Z_STRLEN_P(str) + 1);
memcpy(s, Z_STRVAL_P(str), Z_STRLEN_P(str) + 1);
Z_STRVAL_P(str) = s;
}
while (pos >= 0) {
ch = s[pos];
if (ch >= 'a' && ch <= 'z') {
@ -1753,7 +1772,7 @@ ZEND_API int increment_function(zval *op1) /* {{{ */
switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
case IS_LONG:
efree(Z_STRVAL_P(op1));
str_efree(Z_STRVAL_P(op1));
if (lval == LONG_MAX) {
/* switch to double */
double d = (double)lval;
@ -1763,7 +1782,7 @@ ZEND_API int increment_function(zval *op1) /* {{{ */
}
break;
case IS_DOUBLE:
efree(Z_STRVAL_P(op1));
str_efree(Z_STRVAL_P(op1));
ZVAL_DOUBLE(op1, dval+1);
break;
default:
@ -1879,6 +1898,9 @@ ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint
{
int retval;
if (s1 == s2) {
return 0;
}
retval = memcmp(s1, s2, MIN(len1, len2));
if (!retval) {
return (len1 - len2);
@ -1892,6 +1914,9 @@ ZEND_API int zend_binary_strncmp(const char *s1, uint len1, const char *s2, uint
{
int retval;
if (s1 == s2) {
return 0;
}
retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
if (!retval) {
return (MIN(length, len1) - MIN(length, len2));
@ -1906,8 +1931,11 @@ ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, u
int len;
int c1, c2;
len = MIN(len1, len2);
if (s1 == s2) {
return 0;
}
len = MIN(len1, len2);
while (len--) {
c1 = zend_tolower((int)*(unsigned char *)s1++);
c2 = zend_tolower((int)*(unsigned char *)s2++);
@ -1925,8 +1953,10 @@ ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2,
int len;
int c1, c2;
if (s1 == s2) {
return 0;
}
len = MIN(length, MIN(len1, len2));
while (len--) {
c1 = zend_tolower((int)*(unsigned char *)s1++);
c2 = zend_tolower((int)*(unsigned char *)s2++);

229
Zend/zend_string.c Normal file
View File

@ -0,0 +1,229 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
/* $Id: $ */
#include "zend.h"
#include "zend_globals.h"
#ifndef ZEND_DEBUG_INTERNED_STRINGS
# define ZEND_DEBUG_INTERNED_STRINGS 0
#endif
#if ZEND_DEBUG_INTERNED_STRINGS
# include <sys/mman.h>
#endif
static char *zend_new_interned_string(char *str, int len, int free_src TSRMLS_DC);
static void zend_interned_strings_snapshot(TSRMLS_D);
static void zend_interned_strings_restore(TSRMLS_D);
void zend_interned_strings_init(TSRMLS_D)
{
#ifndef ZTS
size_t size = 1024 * 1024;
#if ZEND_DEBUG_INTERNED_STRINGS
CG(interned_strings_start) = valloc(size);
#else
CG(interned_strings_start) = malloc(size);
#endif
CG(interned_strings_top) = CG(interned_strings_start);
CG(interned_strings_snapshot_top) = CG(interned_strings_start);
CG(interned_strings_end) = CG(interned_strings_start) + size;
zend_hash_init(&CG(interned_strings), 0, NULL, NULL, 1);
CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
CG(interned_strings).arBuckets = (Bucket **) pecalloc(CG(interned_strings).nTableSize, sizeof(Bucket *), CG(interned_strings).persistent);
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
#endif
#endif
CG(new_interned_string) = zend_new_interned_string;
CG(interned_strings_snapshot) = zend_interned_strings_snapshot;
CG(interned_strings_restore) = zend_interned_strings_restore;
}
void zend_interned_strings_dtor(TSRMLS_D)
{
#ifndef ZTS
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
#endif
free(CG(interned_strings).arBuckets);
free(CG(interned_strings_start));
#endif
}
static char *zend_new_interned_string(char *arKey, int nKeyLength, int free_src TSRMLS_DC)
{
#ifndef ZTS
ulong h;
uint nIndex;
Bucket *p;
if (IS_INTERNED(arKey)) {
return arKey;
}
h = zend_inline_hash_func(arKey, nKeyLength);
nIndex = h & CG(interned_strings).nTableMask;
p = CG(interned_strings).arBuckets[nIndex];
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (free_src) {
efree(arKey);
}
return p->arKey;
}
}
p = p->pNext;
}
if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
CG(interned_strings_end)) {
/* no memory */
return arKey;
}
p = (Bucket *) CG(interned_strings_top);
CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE);
#endif
p->arKey = (char*)(p+1);
memcpy(p->arKey, arKey, nKeyLength);
if (free_src) {
efree(arKey);
}
p->nKeyLength = nKeyLength;
p->h = h;
p->pData = &p->pDataPtr;
p->pDataPtr = p;
p->pNext = CG(interned_strings).arBuckets[nIndex];
p->pLast = NULL;
if (p->pNext) {
p->pNext->pLast = p;
}
HANDLE_BLOCK_INTERRUPTIONS();
p->pListLast = CG(interned_strings).pListTail;
CG(interned_strings).pListTail = p;
p->pListNext = NULL;
if (p->pListLast != NULL) {
p->pListLast->pListNext = p;
}
if (!CG(interned_strings).pListHead) {
CG(interned_strings).pListHead = p;
}
CG(interned_strings).arBuckets[nIndex] = p;
HANDLE_UNBLOCK_INTERRUPTIONS();
CG(interned_strings).nNumOfElements++;
if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
if ((CG(interned_strings).nTableSize << 1) > 0) { /* Let's double the table size */
Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);
if (t) {
HANDLE_BLOCK_INTERRUPTIONS();
CG(interned_strings).arBuckets = t;
CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
zend_hash_rehash(&CG(interned_strings));
HANDLE_UNBLOCK_INTERRUPTIONS();
}
}
}
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
#endif
return p->arKey;
#else
return arKey;
#endif
}
static void zend_interned_strings_snapshot(TSRMLS_D)
{
CG(interned_strings_snapshot_top) = CG(interned_strings_top);
}
static void zend_interned_strings_restore(TSRMLS_D)
{
#ifndef ZTS
Bucket *p;
int i;
#endif
CG(interned_strings_top) = CG(interned_strings_snapshot_top);
#ifndef ZTS
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
#endif
for (i = 0; i < CG(interned_strings).nTableSize; i++) {
p = CG(interned_strings).arBuckets[i];
while (p && p->arKey > CG(interned_strings_top)) {
CG(interned_strings).nNumOfElements--;
if (p->pListLast != NULL) {
p->pListLast->pListNext = p->pListNext;
} else {
CG(interned_strings).pListHead = p->pListNext;
}
if (p->pListNext != NULL) {
p->pListNext->pListLast = p->pListLast;
} else {
CG(interned_strings).pListTail = p->pListLast;
}
p = p->pNext;
}
if (p) {
p->pLast = NULL;
}
CG(interned_strings).arBuckets[i] = p;
}
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
#endif
#endif
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/

67
Zend/zend_string.h Normal file
View File

@ -0,0 +1,67 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Dmitry Stogov <dmitry@zend.com> |
+----------------------------------------------------------------------+
*/
/* $Id: $ */
#ifndef ZEND_STRING_H
#define ZEND_STRING_H
#include "zend.h"
void zend_interned_strings_init(TSRMLS_D);
void zend_interned_strings_dtor(TSRMLS_D);
#ifndef ZTS
#define IS_INTERNED(s) \
(((s) >= CG(interned_strings_start)) && ((s) < CG(interned_strings_end)))
#else
#define IS_INTERNED(s) \
(0)
#endif
#define INTERNED_LEN(s) \
(((Bucket*)(((char*)(s))-sizeof(Bucket)))->nKeyLength)
#define INTERNED_HASH(s) \
(((Bucket*)(((char*)(s))-sizeof(Bucket)))->h)
#define str_efree(s) do { \
if (!IS_INTERNED(s)) { \
efree(s); \
} \
} while (0)
#define str_free(s) do { \
if (!IS_INTERNED(s)) { \
free(s); \
} \
} while (0)
#endif /* ZEND_STRING_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* indent-tabs-mode: t
* End:
*/

View File

@ -77,7 +77,7 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
case IS_STRING:
case IS_CONSTANT:
CHECK_ZVAL_STRING_REL(zvalue);
free(zvalue->value.str.val);
str_free(zvalue->value.str.val);
break;
case IS_ARRAY:
case IS_CONSTANT_ARRAY:
@ -117,7 +117,9 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
case IS_CONSTANT:
case IS_STRING:
CHECK_ZVAL_STRING_REL(zvalue);
zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.len);
if (!IS_INTERNED(zvalue->value.str.val)) {
zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.len);
}
break;
case IS_ARRAY:
case IS_CONSTANT_ARRAY: {

View File

@ -951,6 +951,8 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type
*/
if (OP1_TYPE == IS_CONST) {
hash_value = Z_HASH_P(varname);
} else if (IS_INTERNED(Z_STRVAL_P(varname))) {
hash_value = INTERNED_HASH(Z_STRVAL_P(varname));
} else {
hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1);
}
@ -3115,7 +3117,11 @@ ZEND_VM_C_LABEL(num_index):
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, ZEND_VM_C_GOTO(num_index));
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -3459,7 +3465,11 @@ ZEND_VM_C_LABEL(num_index_dim):
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, ZEND_VM_C_GOTO(num_index_dim));
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -3967,7 +3977,11 @@ ZEND_VM_C_LABEL(num_index_prop):
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, ZEND_VM_C_GOTO(num_index_prop));
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -4419,7 +4433,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
zval_copy_ctor(&c.value);
}
c.flags = CONST_CS; /* non persistent, case sensetive */
c.name = zend_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name));
c.name = IS_INTERNED(Z_STRVAL_P(name)) ? Z_STRVAL_P(name) : zend_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name));
c.name_len = Z_STRLEN_P(name)+1;
c.module_number = PHP_USER_CONSTANT;

View File

@ -1367,6 +1367,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND
*/
if (IS_CONST == IS_CONST) {
hash_value = Z_HASH_P(varname);
} else if (IS_INTERNED(Z_STRVAL_P(varname))) {
hash_value = INTERNED_HASH(Z_STRVAL_P(varname));
} else {
hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1);
}
@ -2889,7 +2891,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -2951,7 +2957,7 @@ static int ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD
zval_copy_ctor(&c.value);
}
c.flags = CONST_CS; /* non persistent, case sensetive */
c.name = zend_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name));
c.name = IS_INTERNED(Z_STRVAL_P(name)) ? Z_STRVAL_P(name) : zend_strndup(Z_STRVAL_P(name), Z_STRLEN_P(name));
c.name_len = Z_STRLEN_P(name)+1;
c.module_number = PHP_USER_CONSTANT;
@ -3399,7 +3405,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -3875,7 +3885,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -4075,7 +4089,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -4565,7 +4583,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -4685,6 +4707,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_O
*/
if (IS_TMP_VAR == IS_CONST) {
hash_value = Z_HASH_P(varname);
} else if (IS_INTERNED(Z_STRVAL_P(varname))) {
hash_value = INTERNED_HASH(Z_STRVAL_P(varname));
} else {
hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1);
}
@ -6175,7 +6199,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -6651,7 +6679,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -7127,7 +7159,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -7230,7 +7266,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -7703,7 +7743,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -7981,6 +8025,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_O
*/
if (IS_VAR == IS_CONST) {
hash_value = Z_HASH_P(varname);
} else if (IS_INTERNED(Z_STRVAL_P(varname))) {
hash_value = INTERNED_HASH(Z_STRVAL_P(varname));
} else {
hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1);
}
@ -10759,7 +10805,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -10834,7 +10884,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -10974,7 +11028,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -12528,7 +12586,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -12603,7 +12665,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -12743,7 +12809,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -14348,7 +14418,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -14423,7 +14497,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -14563,7 +14641,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -15230,7 +15312,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -16764,7 +16850,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -16839,7 +16929,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -16979,7 +17073,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -18041,7 +18139,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -18179,7 +18281,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -19108,7 +19214,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -19246,7 +19356,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -20175,7 +20289,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -20313,7 +20431,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -21501,7 +21623,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -21639,7 +21765,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -21975,6 +22105,8 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OP
*/
if (IS_CV == IS_CONST) {
hash_value = Z_HASH_P(varname);
} else if (IS_INTERNED(Z_STRVAL_P(varname))) {
hash_value = INTERNED_HASH(Z_STRVAL_P(varname));
} else {
hash_value = zend_hash_func(Z_STRVAL_P(varname), Z_STRLEN_P(varname)+1);
}
@ -24436,7 +24568,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -24511,7 +24647,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -24649,7 +24789,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -26096,7 +26240,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -26171,7 +26319,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -26309,7 +26461,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -27806,7 +27962,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -27881,7 +28041,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -28019,7 +28183,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;
@ -28585,7 +28753,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -30013,7 +30185,11 @@ num_index:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
zend_hash_quick_update(Z_ARRVAL_P(array_ptr), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, &expr_ptr, sizeof(zval *), NULL);
break;
@ -30088,7 +30264,11 @@ num_index_dim:
hval = Z_HASH_P(offset);
} else {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_dim);
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_del(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval) == SUCCESS &&
ht == &EG(symbol_table)) {
@ -30226,7 +30406,11 @@ num_index_prop:
if (!prop_dim) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, index, goto num_index_prop);
}
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
hval = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
}
}
if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) {
isset = 1;

View File

@ -1424,7 +1424,7 @@ PHP_ADD_SOURCES(Zend, \
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
zend_closures.c zend_float.c)
zend_closures.c zend_float.c zend_string.c)
if test -r "$abs_srcdir/Zend/zend_objects.c"; then
PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)

View File

@ -51,7 +51,7 @@ static void php_filter_encode_html(zval *value, const unsigned char *chars)
}
smart_str_0(&str);
efree(Z_STRVAL_P(value));
str_efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = str.c;
Z_STRLEN_P(value) = str.len;
}
@ -102,7 +102,7 @@ static void php_filter_encode_url(zval *value, const unsigned char* chars, const
s++;
}
*p = '\0';
efree(Z_STRVAL_P(value));
str_efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = (char *)str;
Z_STRLEN_P(value) = p - str;
}
@ -131,7 +131,7 @@ static void php_filter_strip(zval *value, long flags)
}
/* update zval string data */
buf[c] = '\0';
efree(Z_STRVAL_P(value));
str_efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = (char *)buf;
Z_STRLEN_P(value) = c;
}
@ -169,7 +169,7 @@ static void filter_map_apply(zval *value, filter_map *map)
}
/* update zval string data */
buf[c] = '\0';
efree(Z_STRVAL_P(value));
str_efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = (char *)buf;
Z_STRLEN_P(value) = c;
}
@ -254,7 +254,7 @@ void php_filter_full_special_chars(PHP_INPUT_FILTER_PARAM_DECL)
quotes = ENT_NOQUOTES;
}
buf = php_escape_html_entities_ex(Z_STRVAL_P(value), Z_STRLEN_P(value), &len, 1, quotes, SG(default_charset), 0 TSRMLS_CC);
efree(Z_STRVAL_P(value));
str_efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = buf;
Z_STRLEN_P(value) = len;
}
@ -365,7 +365,7 @@ void php_filter_magic_quotes(PHP_INPUT_FILTER_PARAM_DECL)
/* just call php_addslashes quotes */
buf = php_addslashes(Z_STRVAL_P(value), Z_STRLEN_P(value), &len, 0 TSRMLS_CC);
efree(Z_STRVAL_P(value));
str_efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = buf;
Z_STRLEN_P(value) = len;
}

View File

@ -1736,31 +1736,30 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
static int phar_analyze_path(const char *fname, const char *ext, int ext_len, int for_create TSRMLS_DC) /* {{{ */
{
php_stream_statbuf ssb;
char *realpath, old, *a = (char *)(ext + ext_len);
char *realpath;
char *filename = estrndup(fname, (ext - fname) + ext_len);
old = *a;
*a = '\0';
if ((realpath = expand_filepath(fname, NULL TSRMLS_CC))) {
if ((realpath = expand_filepath(filename, NULL TSRMLS_CC))) {
#ifdef PHP_WIN32
phar_unixify_path_separators(realpath, strlen(realpath));
#endif
if (zend_hash_exists(&(PHAR_GLOBALS->phar_fname_map), realpath, strlen(realpath))) {
*a = old;
efree(realpath);
efree(filename);
return SUCCESS;
}
if (PHAR_G(manifest_cached) && zend_hash_exists(&cached_phars, realpath, strlen(realpath))) {
*a = old;
efree(realpath);
efree(filename);
return SUCCESS;
}
efree(realpath);
}
if (SUCCESS == php_stream_stat_path((char *) fname, &ssb)) {
*a = old;
if (SUCCESS == php_stream_stat_path((char *) filename, &ssb)) {
efree(filename);
if (ssb.sb.st_mode & S_IFDIR) {
return FAILURE;
@ -1775,57 +1774,56 @@ static int phar_analyze_path(const char *fname, const char *ext, int ext_len, in
char *slash;
if (!for_create) {
*a = old;
efree(filename);
return FAILURE;
}
slash = (char *) strrchr(fname, '/');
*a = old;
slash = (char *) strrchr(filename, '/');
if (slash) {
old = *slash;
*slash = '\0';
}
if (SUCCESS != php_stream_stat_path((char *) fname, &ssb)) {
if (slash) {
*slash = old;
} else {
if (!(realpath = expand_filepath(fname, NULL TSRMLS_CC))) {
if (SUCCESS != php_stream_stat_path((char *) filename, &ssb)) {
if (!slash) {
if (!(realpath = expand_filepath(filename, NULL TSRMLS_CC))) {
efree(filename);
return FAILURE;
}
#ifdef PHP_WIN32
phar_unixify_path_separators(realpath, strlen(realpath));
#endif
a = strstr(realpath, fname) + ((ext - fname) + ext_len);
*a = '\0';
slash = strstr(realpath, filename) + ((ext - fname) + ext_len);
*slash = '\0';
slash = strrchr(realpath, '/');
if (slash) {
*slash = '\0';
} else {
efree(realpath);
efree(filename);
return FAILURE;
}
if (SUCCESS != php_stream_stat_path(realpath, &ssb)) {
efree(realpath);
efree(filename);
return FAILURE;
}
efree(realpath);
if (ssb.sb.st_mode & S_IFDIR) {
efree(filename);
return SUCCESS;
}
}
efree(filename);
return FAILURE;
}
if (slash) {
*slash = old;
}
efree(filename);
if (ssb.sb.st_mode & S_IFDIR) {
return SUCCESS;

View File

@ -1653,24 +1653,28 @@ PHP_FUNCTION(range)
high = (unsigned char *)Z_STRVAL_P(zhigh);
if (*low > *high) { /* Negative Steps */
unsigned char ch = *low;
if (lstep <= 0) {
err = 1;
goto err;
}
for (; *low >= *high; (*low) -= (unsigned int)lstep) {
add_next_index_stringl(return_value, (const char *)low, 1, 1);
if (((signed int)*low - lstep) < 0) {
for (; ch >= *high; ch -= (unsigned int)lstep) {
add_next_index_stringl(return_value, (const char *)&ch, 1, 1);
if (((signed int)ch - lstep) < 0) {
break;
}
}
} else if (*high > *low) { /* Positive Steps */
unsigned char ch = *low;
if (lstep <= 0) {
err = 1;
goto err;
}
for (; *low <= *high; (*low) += (unsigned int)lstep) {
add_next_index_stringl(return_value, (const char *)low, 1, 1);
if (((signed int)*low + lstep) > 255) {
for (; ch <= *high; ch += (unsigned int)lstep) {
add_next_index_stringl(return_value, (const char *)&ch, 1, 1);
if (((signed int)ch + lstep) > 255) {
break;
}
}

View File

@ -3589,7 +3589,7 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval **subje
replace_value, replace_len, &Z_STRLEN(temp_result), case_sensitivity, replace_count);
}
efree(Z_STRVAL_P(result));
str_efree(Z_STRVAL_P(result));
Z_STRVAL_P(result) = Z_STRVAL(temp_result);
Z_STRLEN_P(result) = Z_STRLEN(temp_result);
@ -4244,6 +4244,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, int *stateptr, char *allow,
char *tbuf, *buf, *p, *tp, *rp, c, lc;
int br, i=0, depth=0, in_q = 0;
int state = 0, pos;
char *allow_free;
if (stateptr)
state = *stateptr;
@ -4255,7 +4256,12 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, int *stateptr, char *allow,
rp = rbuf;
br = 0;
if (allow) {
php_strtolower(allow, allow_len);
if (IS_INTERNED(allow)) {
allow_free = allow = zend_str_tolower_dup(allow, allow_len);
} else {
allow_free = NULL;
php_strtolower(allow, allow_len);
}
tbuf = emalloc(PHP_TAG_BUF_SIZE + 1);
tp = tbuf;
} else {
@ -4494,8 +4500,12 @@ reg_char:
*rp = '\0';
}
efree(buf);
if (allow)
if (allow) {
efree(tbuf);
if (allow_free) {
efree(allow_free);
}
}
if (stateptr)
*stateptr = state;

View File

@ -325,7 +325,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
zend_object_handlers.c zend_objects_API.c \
zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \
zend_float.c");
zend_float.c zend_string.c");
if (VCVERS == 1200) {
AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1);