Commit 00f4cd6b800 for php.net
commit 00f4cd6b800872c6220257f9463f683578cfb624
Author: Weilin Du <weilindu@php.net>
Date: Sat Jul 25 01:06:29 2026 +0800
Refactor various raw C-string concatenation to use existing API (#22879)
In #21607 we introduce several inline helpers for raw C-string concatenation.
This PR use them to refactor several manual C string construction.
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 0a7a62eae9a..6f7cc8a6552 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -1943,10 +1943,10 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int
/* ext/phar has to load phar's metadata into memory */
if (persistent_script->is_phar) {
php_stream_statbuf ssb;
- char *fname = emalloc(sizeof("phar://") + ZSTR_LEN(persistent_script->script.filename));
-
- memcpy(fname, "phar://", sizeof("phar://") - 1);
- memcpy(fname + sizeof("phar://") - 1, ZSTR_VAL(persistent_script->script.filename), ZSTR_LEN(persistent_script->script.filename) + 1);
+ char *fname = zend_cstr_concat(
+ "phar://", sizeof("phar://") - 1,
+ ZSTR_VAL(persistent_script->script.filename),
+ ZSTR_LEN(persistent_script->script.filename));
php_stream_stat_path(fname, &ssb);
efree(fname);
}
@@ -2457,10 +2457,10 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
/* ext/phar has to load phar's metadata into memory */
if (persistent_script->is_phar) {
php_stream_statbuf ssb;
- char *fname = emalloc(sizeof("phar://") + ZSTR_LEN(persistent_script->script.filename));
-
- memcpy(fname, "phar://", sizeof("phar://") - 1);
- memcpy(fname + sizeof("phar://") - 1, ZSTR_VAL(persistent_script->script.filename), ZSTR_LEN(persistent_script->script.filename) + 1);
+ char *fname = zend_cstr_concat(
+ "phar://", sizeof("phar://") - 1,
+ ZSTR_VAL(persistent_script->script.filename),
+ ZSTR_LEN(persistent_script->script.filename));
php_stream_stat_path(fname, &ssb);
efree(fname);
}
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index 794e75a1716..265b47e52dc 100644
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -746,13 +746,10 @@ PHP_FUNCTION(pcntl_exec)
zend_string_addref(key);
}
- /* Length of element + equal sign + length of key + null */
- *pair = safe_emalloc(ZSTR_LEN(element_str) + 1, sizeof(char), ZSTR_LEN(key) + 1);
- /* Copy key=element + final null byte into buffer */
- memcpy(*pair, ZSTR_VAL(key), ZSTR_LEN(key));
- (*pair)[ZSTR_LEN(key)] = '=';
- /* Copy null byte */
- memcpy(*pair + ZSTR_LEN(key) + 1, ZSTR_VAL(element_str), ZSTR_LEN(element_str) + 1);
+ *pair = zend_cstr_concat3(
+ ZSTR_VAL(key), ZSTR_LEN(key),
+ "=", 1,
+ ZSTR_VAL(element_str), ZSTR_LEN(element_str));
/* Cleanup */
zend_string_release_ex(key, false);
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index 8f5e22640cc..52aae986dee 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -392,11 +392,10 @@ static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
return NULL;
}
quotedlen = tmp_len + 1;
- quoted = emalloc(quotedlen + 1);
- memcpy(quoted+1, escaped, quotedlen-2);
- quoted[0] = '\'';
- quoted[quotedlen-1] = '\'';
- quoted[quotedlen] = '\0';
+ quoted = zend_cstr_concat3(
+ "'", 1,
+ (const char *) escaped, quotedlen - 2,
+ "'", 1);
PQfreemem(escaped);
break;
default:
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index 0ea766c12b4..87ccbe3424a 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -3433,10 +3433,8 @@ static zend_result pgsql_copy_from_query(PGconn *pgsql, PGresult *pgsql_result,
int result;
if (ZSTR_LEN(tmp) > 0 && ZSTR_VAL(tmp)[ZSTR_LEN(tmp) - 1] != '\n') {
- char *zquery = emalloc(ZSTR_LEN(tmp) + 2);
- memcpy(zquery, ZSTR_VAL(tmp), ZSTR_LEN(tmp));
- zquery[ZSTR_LEN(tmp)] = '\n';
- zquery[ZSTR_LEN(tmp) + 1] = '\0';
+ char *zquery = zend_cstr_append_char(
+ ZSTR_VAL(tmp), ZSTR_LEN(tmp), '\n');
result = PQputCopyData(pgsql, zquery, ZSTR_LEN(tmp) + 1);
efree(zquery);
} else {
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 0139f0889a8..8a330a954b8 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -633,9 +633,9 @@ PHP_METHOD(Phar, webPhar)
IS_STRING == Z_TYPE_P(z_path_info)) {
entry_len = Z_STRLEN_P(z_path_info);
entry = estrndup(Z_STRVAL_P(z_path_info), entry_len);
- path_info = emalloc(Z_STRLEN_P(z_script_name) + entry_len + 1);
- memcpy(path_info, Z_STRVAL_P(z_script_name), Z_STRLEN_P(z_script_name));
- memcpy(path_info + Z_STRLEN_P(z_script_name), entry, entry_len + 1);
+ path_info = zend_cstr_concat(
+ Z_STRVAL_P(z_script_name), Z_STRLEN_P(z_script_name),
+ entry, entry_len);
free_pathinfo = 1;
} else {
entry_len = 0;
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index 73886af5a56..77d73a2326d 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -85,12 +85,10 @@ static sdlTypePtr get_element(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
size_t ns_len = xmlStrlen(nsptr->href);
size_t type_len = strlen(cptype);
size_t len = ns_len + type_len + 1;
- char *nscat = emalloc(len + 1);
-
- memcpy(nscat, nsptr->href, ns_len);
- nscat[ns_len] = ':';
- memcpy(nscat+ns_len+1, cptype, type_len);
- nscat[len] = '\0';
+ char *nscat = zend_cstr_concat3(
+ (const char *) nsptr->href, ns_len,
+ ":", 1,
+ cptype, type_len);
if ((sdl_type = zend_hash_str_find_ptr(sdl->elements, nscat, len)) != NULL) {
ret = sdl_type;
@@ -117,13 +115,10 @@ encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
size_t type_len = strlen(type);
size_t len = ns_len + type_len + 1;
- nscat = emalloc(len + 1);
- if (ns) {
- memcpy(nscat, ns, ns_len);
- }
- nscat[ns_len] = ':';
- memcpy(nscat+ns_len+1, type, type_len);
- nscat[len] = '\0';
+ nscat = zend_cstr_concat3(
+ ns, ns_len,
+ ":", 1,
+ type, type_len);
enc = get_encoder_ex(sdl, nscat, len);
@@ -138,11 +133,10 @@ encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
enc_ns_len = sizeof(XSD_NAMESPACE)-1;
enc_len = enc_ns_len + type_len + 1;
- enc_nscat = emalloc(enc_len + 1);
- memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
- enc_nscat[enc_ns_len] = ':';
- memcpy(enc_nscat+enc_ns_len+1, type, type_len);
- enc_nscat[enc_len] = '\0';
+ enc_nscat = zend_cstr_concat3(
+ XSD_NAMESPACE, enc_ns_len,
+ ":", 1,
+ type, type_len);
enc = get_encoder_ex(NULL, enc_nscat, enc_len);
efree(enc_nscat);
@@ -1407,11 +1401,10 @@ static void sdl_deserialize_encoder(encodePtr enc, sdlTypePtr *types, char **in)
enc_ns_len = sizeof(XSD_NAMESPACE)-1;
enc_len = enc_ns_len + type_len + 1;
- enc_nscat = emalloc(enc_len + 1);
- memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
- enc_nscat[enc_ns_len] = ':';
- memcpy(enc_nscat+enc_ns_len+1, enc->details.type_str, type_len);
- enc_nscat[enc_len] = '\0';
+ enc_nscat = zend_cstr_concat3(
+ XSD_NAMESPACE, enc_ns_len,
+ ":", 1,
+ enc->details.type_str, type_len);
real_enc = get_encoder_ex(NULL, enc_nscat, enc_len);
efree(enc_nscat);
diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c
index e1a8c1868b9..79d45b76396 100644
--- a/ext/standard/fsock.c
+++ b/ext/standard/fsock.c
@@ -29,17 +29,10 @@ static size_t php_fsockopen_format_host_port(char **message, const char *prefix,
int portlen = snprintf(portbuf, sizeof(portbuf), ":" ZEND_LONG_FMT, port);
size_t total_len = prefix_len + host_len + portlen;
- char *result = emalloc(total_len + 1);
-
- if (prefix_len > 0) {
- memcpy(result, prefix, prefix_len);
- }
- memcpy(result + prefix_len, host, host_len);
- memcpy(result + prefix_len + host_len, portbuf, portlen);
-
- result[total_len] = '\0';
-
- *message = result;
+ *message = zend_cstr_concat3(
+ prefix, prefix_len,
+ host, host_len,
+ portbuf, portlen);
return total_len;
}
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index a41007b7aa8..33b0dadb900 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -1765,10 +1765,7 @@ PHP_METHOD(ZipArchive, addEmptyDir)
}
if (dirname[dirname_len-1] != '/') {
- s=(char *)safe_emalloc(dirname_len, 1, 2);
- strcpy(s, dirname);
- s[dirname_len] = '/';
- s[dirname_len+1] = '\0';
+ s = zend_cstr_append_char(dirname, dirname_len, '/');
} else {
s = dirname;
}
diff --git a/main/SAPI.c b/main/SAPI.c
index 62e1c89e4bb..58e85539d54 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -369,10 +369,10 @@ SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len)
if (*mimetype != NULL) {
if (*charset && strncmp(*mimetype, "text/", 5) == 0 && strstr(*mimetype, "charset=") == NULL) {
newlen = len + (sizeof(";charset=")-1) + strlen(charset);
- newtype = emalloc(newlen + 1);
- PHP_STRLCPY(newtype, *mimetype, newlen + 1, len);
- strlcat(newtype, ";charset=", newlen + 1);
- strlcat(newtype, charset, newlen + 1);
+ newtype = zend_cstr_concat3(
+ *mimetype, len,
+ ";charset=", sizeof(";charset=")-1,
+ charset, strlen(charset));
efree(*mimetype);
*mimetype = newtype;
return newlen;
@@ -878,10 +878,9 @@ SAPI_API int sapi_send_headers(void)
SG(sapi_headers).mimetype = default_mimetype;
default_header.header_len = sizeof("Content-type: ") - 1 + len;
- default_header.header = emalloc(default_header.header_len + 1);
-
- memcpy(default_header.header, "Content-type: ", sizeof("Content-type: ") - 1);
- memcpy(default_header.header + sizeof("Content-type: ") - 1, SG(sapi_headers).mimetype, len + 1);
+ default_header.header = zend_cstr_concat(
+ "Content-type: ", sizeof("Content-type: ") - 1,
+ SG(sapi_headers).mimetype, len);
sapi_header_add_op(SAPI_HEADER_ADD, &default_header);
} else {
diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c
index 3a8435f9e6c..82722538748 100644
--- a/sapi/fpm/fpm/fpm_main.c
+++ b/sapi/fpm/fpm/fpm_main.c
@@ -568,15 +568,10 @@ static void sapi_cgi_register_variables(zval *track_vars_array) /* {{{ */
unsigned int path_info_len = path_info ? strlen(path_info) : 0;
php_self_len = script_name_len + path_info_len;
- php_self = emalloc(php_self_len + 1);
-
/* Concat script_name and path_info into php_self */
- if (script_name) {
- memcpy(php_self, script_name, script_name_len + 1);
- }
- if (path_info) {
- memcpy(php_self + script_name_len, path_info, path_info_len + 1);
- }
+ php_self = zend_cstr_concat(
+ script_name, script_name_len,
+ path_info, path_info_len);
/* Build the special-case PHP_SELF variable for the CGI version */
if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, php_self_len, &php_self_len)) {
@@ -1235,12 +1230,9 @@ static void init_request_info(void)
/* PATH_TRANSLATED = DOCUMENT_ROOT + PATH_INFO */
path_translated_len = l + (env_path_info ? strlen(env_path_info) : 0);
- path_translated = (char *) emalloc(path_translated_len + 1);
- memcpy(path_translated, env_document_root, l);
- if (env_path_info) {
- memcpy(path_translated + l, env_path_info, (path_translated_len - l));
- }
- path_translated[path_translated_len] = '\0';
+ path_translated = zend_cstr_concat(
+ env_document_root, l,
+ env_path_info, path_translated_len - l);
if (orig_path_translated) {
FCGI_PUTENV(request, "ORIG_PATH_TRANSLATED", orig_path_translated);
}
@@ -1254,12 +1246,9 @@ static void init_request_info(void)
int path_translated_len = ptlen + (env_path_info ? strlen(env_path_info) : 0);
char *path_translated = NULL;
- path_translated = (char *) emalloc(path_translated_len + 1);
- memcpy(path_translated, pt, ptlen);
- if (env_path_info) {
- memcpy(path_translated + ptlen, env_path_info, path_translated_len - ptlen);
- }
- path_translated[path_translated_len] = '\0';
+ path_translated = zend_cstr_concat(
+ pt, ptlen,
+ env_path_info, path_translated_len - ptlen);
if (orig_path_translated) {
FCGI_PUTENV(request, "ORIG_PATH_TRANSLATED", orig_path_translated);
}
diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c
index 831595939f6..c259a0d1ace 100644
--- a/sapi/phpdbg/phpdbg_utils.c
+++ b/sapi/phpdbg/phpdbg_utils.c
@@ -672,11 +672,7 @@ char *phpdbg_short_zval_print(zval *zv, int maxlen) /* {{{ */
/* Make sure it looks like a float */
if (zend_finite(Z_DVAL_P(zv)) && !strchr(decode, '.')) {
size_t len = strlen(decode);
- char *decode2 = emalloc(len + strlen(".0") + 1);
- memcpy(decode2, decode, len);
- decode2[len] = '.';
- decode2[len+1] = '0';
- decode2[len+2] = '\0';
+ char *decode2 = zend_cstr_concat(decode, len, ".0", strlen(".0"));
efree(decode);
decode = decode2;
}
diff --git a/win32/registry.c b/win32/registry.c
index 3597d57c85a..8445fffd11b 100644
--- a/win32/registry.c
+++ b/win32/registry.c
@@ -49,9 +49,9 @@ static int OpenPhpRegistryKey(char* sub_key, HKEY *hKey)
LONG ret;
main_key_len = strlen(*key_name);
- reg_key = emalloc(main_key_len + sub_key_len + 1);
- memcpy(reg_key, *key_name, main_key_len);
- memcpy(reg_key + main_key_len, sub_key, sub_key_len + 1);
+ reg_key = zend_cstr_concat(
+ *key_name, main_key_len,
+ sub_key, sub_key_len);
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_key, 0, KEY_READ, hKey);
efree(reg_key);