diff --git a/Zend/zend_API.c b/Zend/zend_API.c index b54996bcae3..23a9139c8e2 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -300,6 +300,45 @@ static int parse_arg_object_to_string(zval *arg, char **p, int *pl, int type TSR } /* }}} */ +static int parse_arg_object_to_str(zval *arg, zend_string **str, int type TSRMLS_DC) /* {{{ */ +{ + if (Z_OBJ_HANDLER_P(arg, cast_object)) { + zval obj; + if (Z_OBJ_HANDLER_P(arg, cast_object)(arg, &obj, type TSRMLS_CC) == SUCCESS) { + zval_ptr_dtor(arg); + ZVAL_COPY_VALUE(arg, &obj); + *str = Z_STR_P(arg); + return SUCCESS; + } + } + /* Standard PHP objects */ + if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) { + SEPARATE_ZVAL_IF_NOT_REF(arg); + if (zend_std_cast_object_tostring(arg, arg, type TSRMLS_CC) == SUCCESS) { + *str = Z_STR_P(arg); + return SUCCESS; + } + } + if (!Z_OBJ_HANDLER_P(arg, cast_object) && Z_OBJ_HANDLER_P(arg, get)) { + int use_copy; + zval *z = Z_OBJ_HANDLER_P(arg, get)(arg TSRMLS_CC); + Z_ADDREF_P(z); + if(Z_TYPE_P(z) != IS_OBJECT) { + zval_dtor(arg); + Z_TYPE_P(arg) = IS_NULL; + zend_make_printable_zval(z, arg, &use_copy); + if (!use_copy) { + ZVAL_ZVAL(arg, z, 1, 1); + } + *str = Z_STR_P(arg); + return SUCCESS; + } + zval_ptr_dtor(z); + } + return FAILURE; +} +/* }}} */ + static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error, int *severity TSRMLS_DC) /* {{{ */ { const char *spec_walk = *spec; @@ -498,11 +537,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons break; case IS_OBJECT: { - char *p; - int pl; - - if (parse_arg_object_to_string(arg, &p, &pl, IS_STRING TSRMLS_CC) == SUCCESS) { - *str = STR_INIT(p, pl, 0); + if (parse_arg_object_to_str(arg, str, IS_STRING TSRMLS_CC) == SUCCESS) { break; } } diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 7a74082b46b..d3bdf87bcab 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -881,14 +881,13 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, zval retval; /* Return value from evaluation */ char *eval_str_end, /* End of eval string */ *match, /* Current match for a backref */ - *esc_match, /* Quote-escaped match */ *walk, /* Used to walk the code string */ *segment, /* Start of segment to append while walking */ walk_last; /* Last walked character */ int match_len; /* Length of the match */ - int esc_match_len; /* Length of the quote-escaped match */ int result_len; /* Length of the result of the evaluation */ int backref; /* Current backref */ + zend_string *esc_match; /* Quote-escaped match */ char *compiled_string_description; smart_str code = {0}; @@ -914,22 +913,19 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject, match = subject + offsets[backref<<1]; match_len = offsets[(backref<<1)+1] - offsets[backref<<1]; if (match_len) { - esc_match = php_addslashes(match, match_len, &esc_match_len, 0 TSRMLS_CC); + esc_match = php_addslashes(match, match_len, 0 TSRMLS_CC); } else { - esc_match = match; - esc_match_len = 0; + esc_match = STR_INIT(match, match_len, 0); } } else { - esc_match = ""; - esc_match_len = 0; + esc_match = STR_EMPTY_ALLOC(); } - smart_str_appendl(&code, esc_match, esc_match_len); + smart_str_appendl(&code, esc_match->val, esc_match->len); segment = walk; /* Clean up and reassign */ - if (esc_match_len) - efree(esc_match); + STR_RELEASE(esc_match); continue; } } diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index c0b03e5838b..5080ddf7c80 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -203,14 +203,8 @@ phar_it: /* uses mmap if possible */ if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) { -#if PHP_API_VERSION < 20100412 - if (PG(magic_quotes_runtime)) { - int newlen; - contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free source string */ - len = newlen; - } -#endif RETVAL_STRINGL(contents, len, 0); + efree(contents); } else if (len == 0) { RETVAL_EMPTY_STRING(); } else { diff --git a/ext/standard/cyr_convert.c b/ext/standard/cyr_convert.c index bc482367afa..280aba5ceca 100644 --- a/ext/standard/cyr_convert.c +++ b/ext/standard/cyr_convert.c @@ -273,17 +273,16 @@ PHP_FUNCTION(convert_cyr_string) { char *input, *fr_cs, *to_cs; int input_len, fr_cs_len, to_cs_len; - unsigned char *str; + zend_string *str; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &input, &input_len, &fr_cs, &fr_cs_len, &to_cs, &to_cs_len) == FAILURE) { return; } - str = (unsigned char*) estrndup(input, input_len); + str = STR_INIT(input, input_len, 0); - php_convert_cyr_string(str, input_len, fr_cs[0], to_cs[0] TSRMLS_CC); -//??? RETVAL_STRING((char *)str, 0); - RETVAL_STRING((char *)str); + php_convert_cyr_string(str->val, str->len, fr_cs[0], to_cs[0] TSRMLS_CC); + RETVAL_STR(str); } /* }}} */ diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index d1ce7f9c2b1..6317c8214cd 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -422,7 +422,7 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) currarg = 1; while (inposval; - prop_len = key->len; - if (key && key->val[0] == '\0' && type != NULL) { - const char *tmp, *prop_name; - int prop_len; + if (key) { + if (key->val[0] == '\0' && type != NULL) { + const char *tmp; - zend_object *zobj = Z_OBJ_P(type); - if (zend_check_property_access(zobj, key TSRMLS_CC) != SUCCESS) { - /* private or protected property access outside of the class */ - continue; + zend_object *zobj = Z_OBJ_P(type); + if (zend_check_property_access(zobj, key TSRMLS_CC) != SUCCESS) { + /* private or protected property access outside of the class */ + continue; + } + zend_unmangle_property_name_ex(key->val, key->len, &tmp, &prop_name, &prop_len); + } else { + prop_name = key->val; + prop_len = key->len; } - zend_unmangle_property_name_ex(key->val, key->len, &tmp, &prop_name, &prop_len); + } else { + prop_name = NULL; + prop_len = 0; } if ((zdata = zend_hash_get_current_data_ex(ht, NULL)) == NULL) { diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 2076eff272d..0f4240ea57d 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -121,7 +121,7 @@ PHPAPI struct lconv *localeconv_r(struct lconv *out); PHPAPI char *php_strtoupper(char *s, size_t len); PHPAPI char *php_strtolower(char *s, size_t len); PHPAPI char *php_strtr(char *str, int len, char *str_from, char *str_to, int trlen); -PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_free TSRMLS_DC); +PHPAPI zend_string *php_addslashes(char *str, int length, int should_free TSRMLS_DC); PHPAPI zend_string *php_addcslashes(const char *str, int length, int freeit, char *what, int wlength TSRMLS_DC); PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC); PHPAPI void php_stripcslashes(char *str, int *len); diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 68567ea0d52..b5608f450d2 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -136,10 +136,10 @@ PHP_FUNCTION(stream_socket_client) if (stream == NULL) { /* host might contain binary characters */ - char *quoted_host = php_addslashes(host, host_len, NULL, 0 TSRMLS_CC); + zend_string *quoted_host = php_addslashes(host, host_len, 0 TSRMLS_CC); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s (%s)", quoted_host, errstr == NULL ? "Unknown error" : errstr); - efree(quoted_host); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s (%s)", quoted_host->val, errstr == NULL ? "Unknown error" : errstr); + STR_RELEASE(quoted_host); } if (hashkey) { diff --git a/ext/standard/string.c b/ext/standard/string.c index f16e3892189..6d81fbf5df0 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -922,12 +922,12 @@ PHP_FUNCTION(wordwrap) /* Multiple character line break or forced cut */ if (linelength > 0) { chk = (int)(textlen/linelength + 1); - newtext = STR_ALLOC(chk * breakcharlen + textlen + 1, 0); + newtext = STR_ALLOC(chk * breakcharlen + textlen, 0); alloced = textlen + chk * breakcharlen + 1; } else { chk = textlen; alloced = textlen * (breakcharlen + 1) + 1; - newtext = STR_ALLOC(textlen * (breakcharlen + 1) + 1, 0); + newtext = STR_ALLOC(textlen * (breakcharlen + 1), 0); } /* now keep track of the actual new text length */ @@ -1080,39 +1080,36 @@ PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_valu Splits a string on string separator and return array of components. If limit is positive only limit number of components is returned. If limit is negative all components except the last abs(limit) are returned. */ PHP_FUNCTION(explode) { - char *str, *delim; - int str_len = 0, delim_len = 0; + zend_string *str, *delim; long limit = LONG_MAX; /* No limit */ zval zdelim, zstr; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &delim, &delim_len, &str, &str_len, &limit) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "SS|l", &delim, &str, &limit) == FAILURE) { return; } - if (delim_len == 0) { + if (delim->len == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter"); RETURN_FALSE; } array_init(return_value); - if (str_len == 0) { + if (str->len == 0) { if (limit >= 0) { add_next_index_stringl(return_value, "", sizeof("") - 1, 1); } return; } -//??? ZVAL_STRINGL(&zstr, str, str_len, 0); -//??? ZVAL_STRINGL(&zdelim, delim, delim_len, 0); - ZVAL_STRINGL(&zstr, str, str_len); - ZVAL_STRINGL(&zdelim, delim, delim_len); + ZVAL_STR(&zstr, str); + ZVAL_STR(&zdelim, delim); if (limit > 1) { php_explode(&zdelim, &zstr, return_value, limit); } else if (limit < 0) { php_explode_negative_limit(&zdelim, &zstr, return_value, limit); } else { - add_index_stringl(return_value, 0, str, str_len, 1); + add_index_stringl(return_value, 0, str->val, str->len, 1); } } /* }}} */ @@ -1524,7 +1521,7 @@ PHP_FUNCTION(pathinfo) char *path, *dirname; int path_len, have_basename; long opt = PHP_PATHINFO_ALL; - zend_string *ret; + zend_string *ret = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &path, &path_len, &opt) == FAILURE) { return; @@ -1579,7 +1576,7 @@ PHP_FUNCTION(pathinfo) add_assoc_stringl(&tmp, "filename", ret->val, idx, 1); } - if (!have_basename && ret) { + if (ret) { STR_RELEASE(ret); } @@ -2278,11 +2275,10 @@ PHP_FUNCTION(substr_replace) zval *from; zval *len = NULL; zval *repl; - char *result; - int result_len; int l = 0; int f; int argc = ZEND_NUM_ARGS(); + zend_string *result; HashPosition pos_str, pos_from, pos_repl, pos_len; zval *tmp_str = NULL, *tmp_from = NULL, *tmp_repl = NULL, *tmp_len= NULL; @@ -2377,17 +2373,16 @@ PHP_FUNCTION(substr_replace) } else { repl_len = Z_STRLEN_P(repl); } - result_len = Z_STRLEN_P(str) - l + repl_len; - result = emalloc(result_len + 1); - memcpy(result, Z_STRVAL_P(str), f); + result = STR_ALLOC(Z_STRLEN_P(str) - l + repl_len, 0); + + memcpy(result->val, Z_STRVAL_P(str), f); if (repl_len) { - memcpy((result + f), (Z_TYPE_P(repl) == IS_ARRAY ? Z_STRVAL_P(tmp_repl) : Z_STRVAL_P(repl)), repl_len); + memcpy((result->val + f), (Z_TYPE_P(repl) == IS_ARRAY ? Z_STRVAL_P(tmp_repl) : Z_STRVAL_P(repl)), repl_len); } - memcpy((result + f + repl_len), Z_STRVAL_P(str) + f + l, Z_STRLEN_P(str) - f - l); - result[result_len] = '\0'; -//??? RETURN_STRINGL(result, result_len, 0); - RETURN_STRINGL(result, result_len); + memcpy((result->val + f + repl_len), Z_STRVAL_P(str) + f + l, Z_STRLEN_P(str) - f - l); + result->val[result->len] = '\0'; + RETURN_STR(result); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Functionality of 'from' and 'len' as arrays is not implemented"); RETURN_STR(STR_COPY(Z_STR_P(str))); @@ -2395,6 +2390,7 @@ PHP_FUNCTION(substr_replace) } else { /* str is array of strings */ zend_string *str_index = NULL; ulong num_index; + int result_len; array_init(return_value); @@ -2520,43 +2516,42 @@ PHP_FUNCTION(substr_replace) result_len += Z_STRLEN_P(repl_str); zend_hash_move_forward_ex(Z_ARRVAL_P(repl), &pos_repl); - result = emalloc(result_len + 1); + result = STR_ALLOC(result_len, 0); - memcpy(result, Z_STRVAL_P(orig_str), f); - memcpy((result + f), Z_STRVAL_P(repl_str), Z_STRLEN_P(repl_str)); - memcpy((result + f + Z_STRLEN_P(repl_str)), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l); + memcpy(result->val, Z_STRVAL_P(orig_str), f); + memcpy((result->val + f), Z_STRVAL_P(repl_str), Z_STRLEN_P(repl_str)); + memcpy((result->val + f + Z_STRLEN_P(repl_str)), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l); if(Z_TYPE_P(tmp_repl) != IS_STRING) { zval_dtor(repl_str); } } else { - result = emalloc(result_len + 1); + result = STR_ALLOC(result_len, 0); - memcpy(result, Z_STRVAL_P(orig_str), f); - memcpy((result + f), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l); + memcpy(result->val, Z_STRVAL_P(orig_str), f); + memcpy((result->val + f), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l); } } else { result_len += Z_STRLEN_P(repl); - result = emalloc(result_len + 1); + result = STR_ALLOC(result_len, 0); - memcpy(result, Z_STRVAL_P(orig_str), f); - memcpy((result + f), Z_STRVAL_P(repl), Z_STRLEN_P(repl)); - memcpy((result + f + Z_STRLEN_P(repl)), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l); + memcpy(result->val, Z_STRVAL_P(orig_str), f); + memcpy((result->val + f), Z_STRVAL_P(repl), Z_STRLEN_P(repl)); + memcpy((result->val + f + Z_STRLEN_P(repl)), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l); } - result[result_len] = '\0'; + result->val[result->len] = '\0'; if (zend_hash_get_current_key_ex(Z_ARRVAL_P(str), &str_index, &num_index, 0, &pos_str) == HASH_KEY_IS_STRING) { -//??? - add_assoc_stringl_ex(return_value, str_index->val, str_index->len, result, result_len, 0); + add_assoc_str(return_value, str_index->val, result); } else { - add_index_stringl(return_value, num_index, result, result_len, 0); + add_index_str(return_value, num_index, result); } if(Z_TYPE_P(tmp_str) != IS_STRING) { zval_dtor(orig_str); } else { -//??? Z_SET_ISREF_TO_P(orig_str, was_ref); +//??? Z_SET_ISREF_TO_P(orig_str, was_ref); } zend_hash_move_forward_ex(Z_ARRVAL_P(str), &pos_str); } /*while*/ @@ -3305,8 +3300,8 @@ PHP_FUNCTION(addcslashes) Escapes single quote, double quotes and backslash characters in a string with backslashes */ PHP_FUNCTION(addslashes) { - char *str, *new_str; - int str_len, new_len; + char *str; + int str_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { return; @@ -3316,13 +3311,7 @@ PHP_FUNCTION(addslashes) RETURN_EMPTY_STRING(); } -//??? RETURN_STRING(php_addslashes(str, -//??? str_len, -//??? &Z_STRLEN_P(return_value), 0 -//??? TSRMLS_CC), 0); - new_str = php_addslashes(str, str_len, &new_len, 0 TSRMLS_CC); - RETVAL_STRINGL(new_str, new_len); - efree(new_str); + RETURN_STR(php_addslashes(str, str_len, 0 TSRMLS_CC)); } /* }}} */ @@ -3449,7 +3438,7 @@ PHPAPI zend_string *php_addcslashes(const char *str, int length, int should_free char *end; char c; int newlen; - zend_string *new_str = STR_ALLOC(4 * (length? length : (length = strlen(str))) + 1, 0); + zend_string *new_str = STR_ALLOC(4 * (length? length : (length = strlen(str))), 0); if (!wlength) { wlength = strlen(what); @@ -3492,25 +3481,21 @@ PHPAPI zend_string *php_addcslashes(const char *str, int length, int should_free /* {{{ php_addslashes */ -PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_free TSRMLS_DC) +PHPAPI zend_string *php_addslashes(char *str, int length, int should_free TSRMLS_DC) { /* maximum string length, worst case situation */ - char *new_str; char *source, *target; char *end; - int local_new_length; + zend_string *new_str; - if (!new_length) { - new_length = &local_new_length; - } if (!str) { - *new_length = 0; - return str; + return STR_EMPTY_ALLOC(); } - new_str = (char *) safe_emalloc(2, (length ? length : (length = strlen(str))), 1); + + new_str = STR_ALLOC(2 * (length ? length : (length = strlen(str))), 0); source = str; end = source + length; - target = new_str; + target = new_str->val; while (source < end) { switch (*source) { @@ -3532,11 +3517,11 @@ PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_f } *target = 0; - *new_length = target - new_str; if (should_free) { //??? STR_FREE(str); } - new_str = (char *) erealloc(new_str, *new_length + 1); + new_str = STR_REALLOC(new_str, target - new_str->val, 0); + return new_str; } /* }}} */ @@ -4373,7 +4358,10 @@ PHP_FUNCTION(setlocale) if (retval) { /* Remember if locale was changed */ if (loc) { -//??? STR_FREE(BG(locale_string)); +//??? STR_FREE(BG(locale_string)); + if (BG(locale_string)) { + efree(BG(locale_string)); + } BG(locale_string) = estrdup(retval); } @@ -4420,11 +4408,7 @@ PHP_FUNCTION(parse_str) zend_rebuild_symbol_table(TSRMLS_C); } //??? Z_ARRVAL(tmp) = EG(active_symbol_table); - array_init(&tmp); - zend_hash_copy(Z_ARRVAL(tmp), EG(active_symbol_table), zval_add_ref); sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC); - zend_hash_copy(EG(active_symbol_table), Z_ARRVAL(tmp), zval_add_ref); - zval_dtor(&tmp); } else { zval ret;