From 7dd46229531a477e1bbbac748c5a60d8789a360b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Wed, 20 Sep 2023 20:22:35 -0300 Subject: [PATCH 1/4] Use a single version of mempcpy(3) While __php_mempcpy is only used by ext/standard/crypt_sha*, the mempcpy "pattern" is used everywhere. This commit removes __php_mempcpy, adds zend_mempcpy and transforms open-coded parts into function calls. --- Zend/zend_operators.h | 9 +++++ Zend/zend_virtual_cwd.c | 3 +- configure.ac | 1 + ext/ffi/ffi.c | 3 +- ext/hash/hash_sha3.c | 3 +- ext/intl/converter/converter.c | 3 +- ext/mbstring/mbstring.c | 3 +- ext/mysqlnd/mysqlnd_wireprotocol.c | 22 +++++------- ext/opcache/jit/zend_jit_helpers.c | 3 +- ext/opcache/shared_alloc_win32.c | 6 ++-- ext/pcre/php_pcre.c | 3 +- ext/standard/crypt_sha256.c | 9 ++--- ext/standard/crypt_sha512.c | 5 ++- ext/standard/file.c | 30 ++++++----------- ext/standard/filters.c | 21 ++++-------- ext/standard/proc_open.c | 6 ++-- ext/standard/string.c | 54 ++++++++++-------------------- ext/standard/var.c | 52 ++++++++++------------------ main/SAPI.c | 6 ++-- main/fastcgi.c | 19 ++++------- sapi/fuzzer/fuzzer-sapi.c | 6 ++-- sapi/phpdbg/phpdbg_help.c | 6 ++-- 22 files changed, 98 insertions(+), 175 deletions(-) diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 2c2d8ed7aa7fb..139be67a6e24b 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -274,6 +274,15 @@ static zend_always_inline size_t zend_strnlen(const char* s, size_t maxlen) #endif } +static zend_always_inline void *zend_mempcpy(void *dest, const void *src, size_t n) +{ +#if defined(HAVE_MEMPCPY) + return mempcpy(dest, src, n); +#else + return (char *)memcpy(dest, src, n) + n; +#endif +} + ZEND_API zend_result ZEND_FASTCALL increment_function(zval *op1); ZEND_API zend_result ZEND_FASTCALL decrement_function(zval *op2); diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 6bff2ad984d02..a35919d8c92e7 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -1681,8 +1681,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type) /* {{{ */ dir = CWDG(cwd).cwd; ptr = command_line = (char *) emalloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1); - memcpy(ptr, "cd ", sizeof("cd ")-1); - ptr += sizeof("cd ")-1; + ptr = zend_mempcpy(ptr, "cd ", sizeof("cd ") - 1); if (CWDG(cwd).cwd_length == 0) { *ptr++ = DEFAULT_SLASH; diff --git a/configure.ac b/configure.ac index 38a37a28bafe5..b683a3cfe5660 100644 --- a/configure.ac +++ b/configure.ac @@ -644,6 +644,7 @@ asprintf \ nanosleep \ memmem \ memrchr \ +mempcpy ) dnl Check for strerror_r, and if its a POSIX-compatible or a GNU specific version. diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 8534ecce63178..a7aad519b4e8c 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -1495,8 +1495,7 @@ static bool zend_ffi_ctype_name_append(zend_ffi_ctype_name_buf *buf, const char if (buf->end + len > buf->buf + MAX_TYPE_NAME_LEN) { return 0; } - memcpy(buf->end, str, len); - buf->end += len; + buf->end = zend_mempcpy(buf->end, str, len); return 1; } /* }}} */ diff --git a/ext/hash/hash_sha3.c b/ext/hash/hash_sha3.c index 3cdebde410946..8a0fddba5b4a6 100644 --- a/ext/hash/hash_sha3.c +++ b/ext/hash/hash_sha3.c @@ -190,8 +190,7 @@ static void PHP_SHA3_Final(unsigned char* digest, // Square output for digest for(;;) { int bs = (len < block_size) ? len : block_size; - memcpy(digest, ctx->state, bs); - digest += bs; + digest = zend_mempcpy(digest, ctx->state, bs); len -= bs; if (!len) break; permute(ctx); diff --git a/ext/intl/converter/converter.c b/ext/intl/converter/converter.c index 6f65cfc2eea69..31d6c6ab4c132 100644 --- a/ext/intl/converter/converter.c +++ b/ext/intl/converter/converter.c @@ -265,8 +265,7 @@ static void php_converter_append_fromUnicode_target(zval *val, UConverterFromUni { size_t vallen = Z_STRLEN_P(val); if (TARGET_CHECK(args, vallen)) { - memcpy(args->target, Z_STRVAL_P(val), vallen); - args->target += vallen; + args->target = zend_mempcpy(args->target, Z_STRVAL_P(val), vallen); } return; } diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 3e59806b86750..7e38aebcdac84 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2607,8 +2607,7 @@ static zend_string* mb_trim_string(zend_string *input, zend_string *marker, cons append_trim_marker: if (ZSTR_LEN(marker) > 0) { MB_CONVERT_BUF_ENSURE((&buf), buf.out, buf.limit, ZSTR_LEN(marker)); - memcpy(buf.out, ZSTR_VAL(marker), ZSTR_LEN(marker)); - buf.out += ZSTR_LEN(marker); + buf.out = zend_mempcpy(buf.out, ZSTR_VAL(marker), ZSTR_LEN(marker)); } /* Even if `enc` is UTF-8, don't mark the output string as valid UTF-8, because diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index fce042ec5be5c..29a4e4d0948d3 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -516,8 +516,7 @@ size_t php_mysqlnd_auth_write(MYSQLND_CONN_DATA * conn, void * _packet) if (packet->send_auth_data || packet->is_change_user_packet) { len = MIN(strlen(packet->user), MYSQLND_MAX_ALLOWED_USER_LEN); - memcpy(p, packet->user, len); - p+= len; + p = zend_mempcpy(p, packet->user, len); *p++ = '\0'; /* defensive coding */ @@ -540,15 +539,14 @@ size_t php_mysqlnd_auth_write(MYSQLND_CONN_DATA * conn, void * _packet) DBG_RETURN(0); } if (packet->auth_data_len) { - memcpy(p, packet->auth_data, packet->auth_data_len); - p+= packet->auth_data_len; + p = zend_mempcpy(p, packet->auth_data, + packet->auth_data_len); } if (packet->db_len > 0) { /* CLIENT_CONNECT_WITH_DB should have been set */ size_t real_db_len = MIN(MYSQLND_MAX_ALLOWED_DB_LEN, packet->db_len); - memcpy(p, packet->db, real_db_len); - p+= real_db_len; + p = zend_mempcpy(p, packet->db, real_db_len); *p++= '\0'; } else if (packet->is_change_user_packet) { *p++= '\0'; @@ -564,8 +562,7 @@ size_t php_mysqlnd_auth_write(MYSQLND_CONN_DATA * conn, void * _packet) if (packet->auth_plugin_name) { len = MIN(strlen(packet->auth_plugin_name), sizeof(buffer) - (p - buffer) - 1); - memcpy(p, packet->auth_plugin_name, len); - p+= len; + p = zend_mempcpy(p, packet->auth_plugin_name, len); *p++= '\0'; } @@ -599,12 +596,10 @@ size_t php_mysqlnd_auth_write(MYSQLND_CONN_DATA * conn, void * _packet) /* copy key */ p = php_mysqlnd_net_store_length(p, ZSTR_LEN(key)); - memcpy(p, ZSTR_VAL(key), ZSTR_LEN(key)); - p+= ZSTR_LEN(key); + p = zend_mempcpy(p, ZSTR_VAL(key), ZSTR_LEN(key)); /* copy value */ p = php_mysqlnd_net_store_length(p, value_len); - memcpy(p, Z_STRVAL_P(entry_value), value_len); - p+= value_len; + p = zend_mempcpy(p, Z_STRVAL_P(entry_value), value_len); } } ZEND_HASH_FOREACH_END(); } @@ -766,8 +761,7 @@ php_mysqlnd_change_auth_response_write(MYSQLND_CONN_DATA * conn, void * _packet) DBG_ENTER("php_mysqlnd_change_auth_response_write"); if (packet->auth_data_len) { - memcpy(p, packet->auth_data, packet->auth_data_len); - p+= packet->auth_data_len; + p = zend_mempcpy(p, packet->auth_data, packet->auth_data_len); } { diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index f9541bd7087dc..82c12a8512b20 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -3150,8 +3150,7 @@ static zend_string* ZEND_FASTCALL zend_jit_rope_end(zend_string **rope, uint32_t char *target = ZSTR_VAL(ret); for (i = 0; i <= count; i++) { - memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i])); - target += ZSTR_LEN(rope[i]); + target = zend_mempcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i])); zend_string_release_ex(rope[i], 0); } *target = '\0'; diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c index 893fe98ec189c..331aff32c9811 100644 --- a/ext/opcache/shared_alloc_win32.c +++ b/ext/opcache/shared_alloc_win32.c @@ -75,13 +75,11 @@ static char *create_name_with_username(char *name) char *p = newname; p += strlcpy(newname, name, MAXPATHLEN + 1); *(p++) = '@'; - memcpy(p, accel_uname_id, 32); - p += 32; + p = zend_mempcpy(p, accel_uname_id, 32); *(p++) = '@'; p += strlcpy(p, sapi_module.name, 21); *(p++) = '@'; - memcpy(p, zend_system_id, 32); - p += 32; + p = zend_mempcpy(p, zend_system_id, 32); *(p++) = '\0'; ZEND_ASSERT(p - newname <= sizeof(newname)); diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 6ad0b6eb76fa4..704d04cbe7654 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1724,8 +1724,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su if (preg_get_backref(&walk, &backref)) { if (backref < count) { match_len = offsets[(backref<<1)+1] - offsets[backref<<1]; - memcpy(walkbuf, subject + offsets[backref<<1], match_len); - walkbuf += match_len; + walkbuf = zend_mempcpy(walkbuf, subject + offsets[backref << 1], match_len); } continue; } diff --git a/ext/standard/crypt_sha256.c b/ext/standard/crypt_sha256.c index 9e86db6020cdf..dbd1c62fd58c5 100644 --- a/ext/standard/crypt_sha256.c +++ b/ext/standard/crypt_sha256.c @@ -37,11 +37,6 @@ char * __php_stpncpy(char *dst, const char *src, size_t len) return strncpy(dst, src, len) + n; } -void * __php_mempcpy(void * dst, const void * src, size_t len) -{ - return (((char *)memcpy(dst, src, len)) + len); -} - #ifndef MIN # define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif @@ -452,7 +447,7 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b ALLOCA_FLAG(use_heap_p_bytes); cp = p_bytes = do_alloca(key_len, use_heap_p_bytes); for (cnt = key_len; cnt >= 32; cnt -= 32) { - cp = __php_mempcpy((void *)cp, (const void *)temp_result, 32); + cp = zend_mempcpy((void *)cp, (const void *)temp_result, 32); } memcpy(cp, temp_result, cnt); @@ -471,7 +466,7 @@ char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int b ALLOCA_FLAG(use_heap_s_bytes); cp = s_bytes = do_alloca(salt_len, use_heap_s_bytes); for (cnt = salt_len; cnt >= 32; cnt -= 32) { - cp = __php_mempcpy(cp, temp_result, 32); + cp = zend_mempcpy(cp, temp_result, 32); } memcpy(cp, temp_result, cnt); diff --git a/ext/standard/crypt_sha512.c b/ext/standard/crypt_sha512.c index 6ead7f2964a48..d854a15604f5d 100644 --- a/ext/standard/crypt_sha512.c +++ b/ext/standard/crypt_sha512.c @@ -27,7 +27,6 @@ # include #endif -extern void * __php_mempcpy(void * dst, const void * src, size_t len); extern char * __php_stpncpy(char *dst, const char *src, size_t len); #ifndef MIN @@ -486,7 +485,7 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen) ALLOCA_FLAG(use_heap_p_bytes); cp = p_bytes = do_alloca(key_len, use_heap_p_bytes); for (cnt = key_len; cnt >= 64; cnt -= 64) { - cp = __php_mempcpy((void *) cp, (const void *)temp_result, 64); + cp = zend_mempcpy((void *) cp, (const void *)temp_result, 64); } memcpy(cp, temp_result, cnt); @@ -506,7 +505,7 @@ php_sha512_crypt_r(const char *key, const char *salt, char *buffer, int buflen) ALLOCA_FLAG(use_heap_s_bytes); cp = s_bytes = do_alloca(salt_len, use_heap_s_bytes); for (cnt = salt_len; cnt >= 64; cnt -= 64) { - cp = __php_mempcpy(cp, temp_result, 64); + cp = zend_mempcpy(cp, temp_result, 64); } memcpy(cp, temp_result, cnt); diff --git a/ext/standard/file.c b/ext/standard/file.c index 5f6452e23d8d9..32cb361115354 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1995,27 +1995,23 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure case 0: switch (state) { case 2: - memcpy(tptr, hunk_begin, bptr - hunk_begin - 1); - tptr += (bptr - hunk_begin - 1); + tptr = zend_mempcpy(tptr, hunk_begin, (bptr - hunk_begin - 1)); hunk_begin = bptr; goto quit_loop_2; case 1: - memcpy(tptr, hunk_begin, bptr - hunk_begin); - tptr += (bptr - hunk_begin); + tptr = zend_mempcpy(tptr, hunk_begin, (bptr - hunk_begin)); hunk_begin = bptr; ZEND_FALLTHROUGH; case 0: { if (hunk_begin != line_end) { - memcpy(tptr, hunk_begin, bptr - hunk_begin); - tptr += (bptr - hunk_begin); + tptr = zend_mempcpy(tptr, hunk_begin, (bptr - hunk_begin)); hunk_begin = bptr; } /* add the embedded line end to the field */ - memcpy(tptr, line_end, line_end_len); - tptr += line_end_len; + tptr = zend_mempcpy(tptr, line_end, line_end_len); /* nothing can be fetched if stream is NULL (e.g. str_getcsv()) */ if (stream == NULL) { @@ -2082,13 +2078,11 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure case 2: /* embedded enclosure ? let's check it */ if (*bptr != enclosure) { /* real enclosure */ - memcpy(tptr, hunk_begin, bptr - hunk_begin - 1); - tptr += (bptr - hunk_begin - 1); + tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin - 1); hunk_begin = bptr; goto quit_loop_2; } - memcpy(tptr, hunk_begin, bptr - hunk_begin); - tptr += (bptr - hunk_begin); + tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin); bptr++; hunk_begin = bptr; state = 0; @@ -2108,14 +2102,12 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure switch (state) { case 2: /* real enclosure */ - memcpy(tptr, hunk_begin, bptr - hunk_begin - 1); - tptr += (bptr - hunk_begin - 1); + tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin - 1); hunk_begin = bptr; goto quit_loop_2; case 1: bptr += inc_len; - memcpy(tptr, hunk_begin, bptr - hunk_begin); - tptr += (bptr - hunk_begin); + tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin); hunk_begin = bptr; state = 0; break; @@ -2153,8 +2145,7 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure } quit_loop_3: - memcpy(tptr, hunk_begin, bptr - hunk_begin); - tptr += (bptr - hunk_begin); + tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin); bptr += inc_len; comp_end = tptr; } else { @@ -2183,8 +2174,7 @@ PHPAPI HashTable *php_fgetcsv(php_stream *stream, char delimiter, char enclosure inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0); } quit_loop_4: - memcpy(tptr, hunk_begin, bptr - hunk_begin); - tptr += (bptr - hunk_begin); + tptr = zend_mempcpy(tptr, hunk_begin, bptr - hunk_begin); comp_end = (char *)php_fgetcsv_lookup_trailing_spaces(temp, tptr - temp); if (*bptr == delimiter) { diff --git a/ext/standard/filters.c b/ext/standard/filters.c index d72c09b7d22b6..2550eb39e4fbe 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -297,8 +297,7 @@ static php_conv_err_t php_conv_base64_encode_flush(php_conv_base64_encode *inst, if (ocnt < inst->lbchars_len) { return PHP_CONV_ERR_TOO_BIG; } - memcpy(pd, inst->lbchars, inst->lbchars_len); - pd += inst->lbchars_len; + pd = zend_mempcpy(pd, inst->lbchars, inst->lbchars_len); ocnt -= inst->lbchars_len; line_ccnt = inst->line_len; } @@ -352,8 +351,7 @@ static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *ins if (ocnt < inst->lbchars_len) { return PHP_CONV_ERR_TOO_BIG; } - memcpy(pd, inst->lbchars, inst->lbchars_len); - pd += inst->lbchars_len; + pd = zend_mempcpy(pd, inst->lbchars, inst->lbchars_len); ocnt -= inst->lbchars_len; line_ccnt = inst->line_len; } @@ -379,8 +377,7 @@ static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *ins if (ocnt < inst->lbchars_len) { return PHP_CONV_ERR_TOO_BIG; } - memcpy(pd, inst->lbchars, inst->lbchars_len); - pd += inst->lbchars_len; + pd = zend_mempcpy(pd, inst->lbchars, inst->lbchars_len); ocnt -= inst->lbchars_len; line_ccnt = inst->line_len; } @@ -407,8 +404,7 @@ static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *ins err = PHP_CONV_ERR_TOO_BIG; goto out; } - memcpy(pd, inst->lbchars, inst->lbchars_len); - pd += inst->lbchars_len; + pd = zend_mempcpy(pd, inst->lbchars, inst->lbchars_len); ocnt -= inst->lbchars_len; line_ccnt = inst->line_len; } @@ -721,8 +717,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins ocnt--; line_ccnt--; - memcpy(pd, inst->lbchars, inst->lbchars_len); - pd += inst->lbchars_len; + pd = zend_mempcpy(pd, inst->lbchars, inst->lbchars_len); ocnt -= inst->lbchars_len; line_ccnt = inst->line_len; } else { @@ -778,8 +773,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins ocnt--; line_ccnt--; - memcpy(pd, inst->lbchars, inst->lbchars_len); - pd += inst->lbchars_len; + pd = zend_mempcpy(pd, inst->lbchars, inst->lbchars_len); ocnt -= inst->lbchars_len; line_ccnt = inst->line_len; } @@ -801,8 +795,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins ocnt--; line_ccnt--; - memcpy(pd, inst->lbchars, inst->lbchars_len); - pd += inst->lbchars_len; + pd = zend_mempcpy(pd, inst->lbchars, inst->lbchars_len); ocnt -= inst->lbchars_len; line_ccnt = inst->line_len; } diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 264a7c6250cb0..f2c0bedc63301 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -203,13 +203,11 @@ static php_process_env _php_array_to_envp(zval *environment) #endif if (key) { - memcpy(p, ZSTR_VAL(key), ZSTR_LEN(key)); - p += ZSTR_LEN(key); + p = zend_mempcpy(p, ZSTR_VAL(key), ZSTR_LEN(key)); *p++ = '='; } - memcpy(p, ZSTR_VAL(str), ZSTR_LEN(str)); - p += ZSTR_LEN(str); + p = zend_mempcpy(p, ZSTR_VAL(str), ZSTR_LEN(str)); *p++ = '\0'; zend_string_release_ex(str, 0); } ZEND_HASH_FOREACH_END(); diff --git a/ext/standard/string.c b/ext/standard/string.c index 70743f4db7085..5d96427e2496c 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1975,18 +1975,14 @@ static zend_string *php_chunk_split(const char *src, size_t srclen, const char * dest = zend_string_safe_alloc(chunks, endlen, srclen, 0); for (p = src, q = ZSTR_VAL(dest); p < (src + srclen - chunklen + 1); ) { - memcpy(q, p, chunklen); - q += chunklen; - memcpy(q, end, endlen); - q += endlen; + q = zend_mempcpy(q, p, chunklen); + q = zend_mempcpy(q, end, endlen); p += chunklen; } if (restlen) { - memcpy(q, p, restlen); - q += restlen; - memcpy(q, end, endlen); - q += endlen; + q = zend_mempcpy(q, p, restlen); + q = zend_mempcpy(q, end, endlen); } *q = '\0'; @@ -2903,24 +2899,20 @@ static zend_string* php_char_to_str_ex(zend_string *str, char from, char *to, si char *p = ZSTR_VAL(str), *e = p + ZSTR_LEN(str), *s = ZSTR_VAL(str); while ((p = memchr(p, from, (e - p)))) { - memcpy(target, s, (p - s)); - target += p - s; - memcpy(target, to, to_len); - target += to_len; + target = zend_mempcpy(target, s, (p - s)); + target = zend_mempcpy(target, to, to_len); p++; s = p; if (--char_count == 0) break; } if (s < e) { - memcpy(target, s, (e - s)); - target += e - s; + target = zend_mempcpy(target, s, e - s); } } else { source_end = ZSTR_VAL(str) + ZSTR_LEN(str); for (source = ZSTR_VAL(str); source < source_end; source++) { if (zend_tolower_ascii(*source) == lc_from) { - memcpy(target, to, to_len); - target += to_len; + target = zend_mempcpy(target, to, to_len); } else { *target = *source; target++; @@ -2980,16 +2972,13 @@ static zend_string *php_str_to_str_ex(zend_string *haystack, e = ZSTR_VAL(new_str); end = ZSTR_VAL(haystack) + ZSTR_LEN(haystack); for (p = ZSTR_VAL(haystack); (r = (char*)php_memnstr(p, needle, needle_len, end)); p = r + needle_len) { - memcpy(e, p, r - p); - e += r - p; - memcpy(e, str, str_len); - e += str_len; + e = zend_mempcpy(e, p, r - p); + e = zend_mempcpy(e, str, str_len); (*replace_count)++; } if (p < end) { - memcpy(e, p, end - p); - e += end - p; + e = zend_mempcpy(e, p, end - p); } *e = '\0'; @@ -3062,16 +3051,13 @@ static zend_string *php_str_to_str_i_ex(zend_string *haystack, const char *lc_ha end = lc_haystack + ZSTR_LEN(haystack); for (p = lc_haystack; (r = (char*)php_memnstr(p, ZSTR_VAL(lc_needle), ZSTR_LEN(lc_needle), end)); p = r + ZSTR_LEN(lc_needle)) { - memcpy(e, ZSTR_VAL(haystack) + (p - lc_haystack), r - p); - e += r - p; - memcpy(e, str, str_len); - e += str_len; + e = zend_mempcpy(e, ZSTR_VAL(haystack) + (p - lc_haystack), r - p); + e = zend_mempcpy(e, str, str_len); (*replace_count)++; } if (p < end) { - memcpy(e, ZSTR_VAL(haystack) + (p - lc_haystack), end - p); - e += end - p; + e = zend_mempcpy(e, ZSTR_VAL(haystack) + (p - lc_haystack), end - p); } *e = '\0'; @@ -3145,15 +3131,12 @@ PHPAPI zend_string *php_str_to_str(const char *haystack, size_t length, const ch s = e = ZSTR_VAL(new_str); end = haystack + length; for (p = haystack; (r = (char*)php_memnstr(p, needle, needle_len, end)); p = r + needle_len) { - memcpy(e, p, r - p); - e += r - p; - memcpy(e, str, str_len); - e += str_len; + e = zend_mempcpy(e, p, r - p); + e = zend_mempcpy(e, str, str_len); } if (p < end) { - memcpy(e, p, end - p); - e += end - p; + e = zend_mempcpy(e, p, end - p); } *e = '\0'; @@ -4908,8 +4891,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_ *(tp++) = '>'; *tp='\0'; if (php_tag_find(tbuf, tp-tbuf, allow)) { - memcpy(rp, tbuf, tp-tbuf); - rp += tp-tbuf; + rp = zend_mempcpy(rp, tbuf, tp - tbuf); } tp = tbuf; } diff --git a/ext/standard/var.c b/ext/standard/var.c index 4f04ff6c0deb3..2975f165789e5 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -725,8 +725,7 @@ static inline void php_var_serialize_long(smart_str *buf, zend_long val) /* {{{ char *s = zend_print_long_to_buf(b + sizeof(b) - 1, val); size_t l = b + sizeof(b) - 1 - s; char *res = smart_str_extend(buf, 2 + l + 1); - memcpy(res, "i:", 2); - res += 2; + res = zend_mempcpy(res, "i:", 2); memcpy(res, s, l); res[l] = ';'; } @@ -738,14 +737,10 @@ static inline void php_var_serialize_string(smart_str *buf, char *str, size_t le char *s = zend_print_long_to_buf(b + sizeof(b) - 1, len); size_t l = b + sizeof(b) - 1 - s; char *res = smart_str_extend(buf, 2 + l + 2 + len + 2); - memcpy(res, "s:", 2); - res += 2; - memcpy(res, s, l); - res += l; - memcpy(res, ":\"", 2); - res += 2; - memcpy(res, str, len); - res += len; + res = zend_mempcpy(res, "s:", 2); + res = zend_mempcpy(res, s, l); + res = zend_mempcpy(res, ":\"", 2); + res = zend_mempcpy(res, str, len); memcpy(res, "\";", 2); } /* }}} */ @@ -760,14 +755,10 @@ static inline bool php_var_serialize_class_name(smart_str *buf, zval *struc) /* char *s = zend_print_long_to_buf(b + sizeof(b) - 1, class_name_len); size_t l = b + sizeof(b) - 1 - s; char *res = smart_str_extend(buf, 2 + l + 2 + class_name_len + 2); - memcpy(res, "O:", 2); - res += 2; - memcpy(res, s, l); - res += l; - memcpy(res, ":\"", 2); - res += 2; - memcpy(res, ZSTR_VAL(class_name), class_name_len); - res += class_name_len; + res = zend_mempcpy(res, "O:", 2); + res = zend_mempcpy(res, s, l); + res = zend_mempcpy(res, ":\"", 2); + res = zend_mempcpy(res, ZSTR_VAL(class_name), class_name_len); memcpy(res, "\":", 2); PHP_CLEANUP_CLASS_ATTRIBUTES(); return incomplete_class; @@ -1037,8 +1028,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ size_t len = strlen(tmp_str); char *res = smart_str_extend(buf, 2 + len + 1); - memcpy(res, "d:", 2); - res += 2; + res = zend_mempcpy(res, "d:", 2); memcpy(res, tmp_str, len); res[len] = ';'; return; @@ -1125,21 +1115,13 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ char *s2 = zend_print_long_to_buf(b2 + sizeof(b2) - 1, serialized_length); size_t l2 = b2 + sizeof(b2) - 1 - s2; char *res = smart_str_extend(buf, 2 + l1 + 2 + ZSTR_LEN(Z_OBJCE_P(struc)->name) + 2 + l2 + 2 + serialized_length + 1); - memcpy(res, "C:", 2); - res += 2; - memcpy(res, s1, l1); - res += l1; - memcpy(res, ":\"", 2); - res += 2; - memcpy(res, ZSTR_VAL(Z_OBJCE_P(struc)->name), ZSTR_LEN(Z_OBJCE_P(struc)->name)); - res += ZSTR_LEN(Z_OBJCE_P(struc)->name); - memcpy(res, "\":", 2); - res += 2; - - memcpy(res, s2, l2); - res += l2; - memcpy(res, ":{", 2); - res += 2; + res = zend_mempcpy(res, "C:", 2); + res = zend_mempcpy(res, s1, l1); + res = zend_mempcpy(res, ":\"", 2); + res = zend_mempcpy(res, ZSTR_VAL(Z_OBJCE_P(struc)->name), ZSTR_LEN(Z_OBJCE_P(struc)->name)); + res = zend_mempcpy(res, "\":", 2); + res = zend_mempcpy(res, s2, l2); + res = zend_mempcpy(res, ":{", 2); memcpy(res, (char *) serialized_data, serialized_length); res[serialized_length] = '}'; } else { diff --git a/main/SAPI.c b/main/SAPI.c index 2e697f9779669..e405702063789 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -322,10 +322,8 @@ static inline char *get_default_content_type(uint32_t prefix_len, uint32_t *len) *len = prefix_len + mimetype_len + sizeof("; charset=") - 1 + charset_len; content_type = (char*)emalloc(*len + 1); p = content_type + prefix_len; - memcpy(p, mimetype, mimetype_len); - p += mimetype_len; - memcpy(p, "; charset=", sizeof("; charset=") - 1); - p += sizeof("; charset=") - 1; + p = zend_mempcpy(p, mimetype, mimetype_len); + p = zend_mempcpy(p, "; charset=", sizeof("; charset=") - 1); memcpy(p, charset, charset_len + 1); } else { *len = prefix_len + mimetype_len; diff --git a/main/fastcgi.c b/main/fastcgi.c index 9c66830137f10..f65d01791af94 100644 --- a/main/fastcgi.c +++ b/main/fastcgi.c @@ -1190,10 +1190,8 @@ static int fcgi_read_request(fcgi_request *req) *p++ = (zlen >> 8) & 0xff; *p++ = zlen & 0xff; } - memcpy(p, q->var, q->var_len); - p += q->var_len; - memcpy(p, Z_STRVAL_P(value), zlen); - p += zlen; + p = zend_mempcpy(p, q->var, q->var_len); + p = zend_mempcpy(p, Z_STRVAL_P(value), zlen); q = q->list_next; } len = (int)(p - buf - sizeof(fcgi_header)); @@ -1597,23 +1595,20 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l if (!req->out_hdr) { open_packet(req, type); } - memcpy(req->out_pos, str, len); - req->out_pos += len; + req->out_pos = zend_mempcpy(req->out_pos, str, len); } else if (len - limit < (int)(sizeof(req->out_buf) - sizeof(fcgi_header))) { if (limit > 0) { if (!req->out_hdr) { open_packet(req, type); } - memcpy(req->out_pos, str, limit); - req->out_pos += limit; + req->out_pos = zend_mempcpy(req->out_pos, str, limit); } if (!fcgi_flush(req, 0)) { return -1; } if (len > limit) { open_packet(req, type); - memcpy(req->out_pos, str + limit, len - limit); - req->out_pos += len - limit; + req->out_pos = zend_mempcpy(req->out_pos, str + limit, len - limit); } } else { int pos = 0; @@ -1649,8 +1644,8 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l } if (pad) { open_packet(req, type); - memcpy(req->out_pos, str + len - rest, rest); - req->out_pos += rest; + req->out_pos = zend_mempcpy(req->out_pos, + str + len - rest, rest); } } #endif diff --git a/sapi/fuzzer/fuzzer-sapi.c b/sapi/fuzzer/fuzzer-sapi.c index d0a9b553aa856..d772f13726b39 100644 --- a/sapi/fuzzer/fuzzer-sapi.c +++ b/sapi/fuzzer/fuzzer-sapi.c @@ -146,12 +146,10 @@ int fuzzer_init_php(const char *extra_ini) } char *p = malloc(ini_len + 1); fuzzer_module.ini_entries = p; - memcpy(p, HARDCODED_INI, sizeof(HARDCODED_INI) - 1); - p += sizeof(HARDCODED_INI) - 1; + p = zend_mempcpy(p, HARDCODED_INI, sizeof(HARDCODED_INI) - 1); if (extra_ini) { *p++ = '\n'; - memcpy(p, extra_ini, extra_ini_len); - p += extra_ini_len; + p = zend_mempcpy(p, extra_ini, extra_ini_len); } *p = '\0'; diff --git a/sapi/phpdbg/phpdbg_help.c b/sapi/phpdbg/phpdbg_help.c index 9766ab7b2e429..ff96a7617e2b4 100644 --- a/sapi/phpdbg/phpdbg_help.c +++ b/sapi/phpdbg/phpdbg_help.c @@ -98,14 +98,12 @@ static void pretty_print(const char *text) } else if (UNEXPECTED(p[0] == '*') && p[1] == '*') { if (bold_escape_len) { in_bold = !in_bold; - memcpy (q, in_bold ? bold_on_escape : bold_off_escape, bold_escape_len); - q += bold_escape_len; + q = zend_mempcpy(q, in_bold ? bold_on_escape : bold_off_escape, bold_escape_len); /* bold on/off has zero print width so line count is unchanged */ } p++; } else if (UNEXPECTED(p[0] == '$') && p[1] == 'P') { - memcpy (q, prompt_escape, prompt_escape_len); - q += prompt_escape_len; + q = zend_mempcpy(q, prompt_escape, prompt_escape_len); line_count += prompt_len; p++; } else if (UNEXPECTED(p[0] == '\\')) { From efbe87cf3b0ac93567ba4ce506575576805e7766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Tue, 19 Dec 2023 21:25:15 -0300 Subject: [PATCH 2/4] apply suggestion from Girgias Co-authored-by: Gina Peter Banyard --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b683a3cfe5660..3091091017600 100644 --- a/configure.ac +++ b/configure.ac @@ -644,7 +644,7 @@ asprintf \ nanosleep \ memmem \ memrchr \ -mempcpy +mempcpy \ ) dnl Check for strerror_r, and if its a POSIX-compatible or a GNU specific version. From 2fbc0cd64bcd48cd446c6fdd108485d91b6a5a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Tue, 19 Dec 2023 21:25:41 -0300 Subject: [PATCH 3/4] Update ext/mysqlnd/mysqlnd_wireprotocol.c suggestion from Girgias Co-authored-by: Gina Peter Banyard --- ext/mysqlnd/mysqlnd_wireprotocol.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 29a4e4d0948d3..d019813f983c7 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -539,8 +539,7 @@ size_t php_mysqlnd_auth_write(MYSQLND_CONN_DATA * conn, void * _packet) DBG_RETURN(0); } if (packet->auth_data_len) { - p = zend_mempcpy(p, packet->auth_data, - packet->auth_data_len); + p = zend_mempcpy(p, packet->auth_data, packet->auth_data_len); } if (packet->db_len > 0) { From d3720b7ec8e388e84eb6f2e35342e856d41311e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Tue, 19 Dec 2023 21:26:08 -0300 Subject: [PATCH 4/4] Suggestion from Girgias Remove line break Co-authored-by: Gina Peter Banyard --- main/fastcgi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main/fastcgi.c b/main/fastcgi.c index f65d01791af94..8e6907ced2e50 100644 --- a/main/fastcgi.c +++ b/main/fastcgi.c @@ -1644,8 +1644,7 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l } if (pad) { open_packet(req, type); - req->out_pos = zend_mempcpy(req->out_pos, - str + len - rest, rest); + req->out_pos = zend_mempcpy(req->out_pos, str + len - rest, rest); } } #endif