1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Avoid string copy in ZipArchive::addFromString() (#20497)

Instead of copying the data we increment the refcount of the string.
This commit is contained in:
Niels Dossche
2025-11-16 05:57:00 -08:00
committed by GitHub
parent 035f95cf5e
commit 5bed2a8920
3 changed files with 9 additions and 7 deletions

View File

@@ -130,3 +130,6 @@ PHP 8.6 UPGRADE NOTES
. Improved performance of array_walk(). . Improved performance of array_walk().
. Improved performance of intval('+0b...', 2) and intval('0b...', 2). . Improved performance of intval('+0b...', 2) and intval('0b...', 2).
. Improved performance of str_split(). . Improved performance of str_split().
- Zip:
. Avoid string copies in ZipArchive::addFromString().

View File

@@ -1014,7 +1014,7 @@ static void php_zip_object_free_storage(zend_object *object) /* {{{ */
if (intern->buffers_cnt>0) { if (intern->buffers_cnt>0) {
for (i=0; i<intern->buffers_cnt; i++) { for (i=0; i<intern->buffers_cnt; i++) {
efree(intern->buffers[i]); zend_string_release(intern->buffers[i]);
} }
efree(intern->buffers); efree(intern->buffers);
} }
@@ -1868,17 +1868,16 @@ PHP_METHOD(ZipArchive, addFromString)
ze_obj = Z_ZIP_P(self); ze_obj = Z_ZIP_P(self);
if (ze_obj->buffers_cnt) { if (ze_obj->buffers_cnt) {
ze_obj->buffers = (char **)safe_erealloc(ze_obj->buffers, sizeof(char *), (ze_obj->buffers_cnt+1), 0); ze_obj->buffers = safe_erealloc(ze_obj->buffers, sizeof(*ze_obj->buffers), (ze_obj->buffers_cnt + 1), 0);
pos = ze_obj->buffers_cnt++; pos = ze_obj->buffers_cnt++;
} else { } else {
ze_obj->buffers = (char **)emalloc(sizeof(char *)); ze_obj->buffers = emalloc(sizeof(*ze_obj->buffers));
ze_obj->buffers_cnt++; ze_obj->buffers_cnt++;
pos = 0; pos = 0;
} }
ze_obj->buffers[pos] = (char *)safe_emalloc(ZSTR_LEN(buffer), 1, 1); ze_obj->buffers[pos] = zend_string_copy(buffer);
memcpy(ze_obj->buffers[pos], ZSTR_VAL(buffer), ZSTR_LEN(buffer) + 1);
zs = zip_source_buffer(intern, ze_obj->buffers[pos], ZSTR_LEN(buffer), 0); zs = zip_source_buffer(intern, ZSTR_VAL(buffer), ZSTR_LEN(buffer), 0);
if (zs == NULL) { if (zs == NULL) {
RETURN_FALSE; RETURN_FALSE;

View File

@@ -68,7 +68,7 @@ typedef struct _ze_zip_read_rsrc {
/* Extends zend object */ /* Extends zend object */
typedef struct _ze_zip_object { typedef struct _ze_zip_object {
struct zip *za; struct zip *za;
char **buffers; zend_string **buffers;
HashTable *prop_handler; HashTable *prop_handler;
char *filename; char *filename;
int filename_len; int filename_len;