Skip to content

Commit 5bed2a8

Browse files
authored
Avoid string copy in ZipArchive::addFromString() (php#20497)
Instead of copying the data we increment the refcount of the string.
1 parent 035f95c commit 5bed2a8

File tree

3 files changed

+9
-7
lines changed

3 files changed

+9
-7
lines changed

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,6 @@ PHP 8.6 UPGRADE NOTES
130130
. Improved performance of array_walk().
131131
. Improved performance of intval('+0b...', 2) and intval('0b...', 2).
132132
. Improved performance of str_split().
133+
134+
- Zip:
135+
. Avoid string copies in ZipArchive::addFromString().

ext/zip/php_zip.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ static void php_zip_object_free_storage(zend_object *object) /* {{{ */
10141014

10151015
if (intern->buffers_cnt>0) {
10161016
for (i=0; i<intern->buffers_cnt; i++) {
1017-
efree(intern->buffers[i]);
1017+
zend_string_release(intern->buffers[i]);
10181018
}
10191019
efree(intern->buffers);
10201020
}
@@ -1868,17 +1868,16 @@ PHP_METHOD(ZipArchive, addFromString)
18681868

18691869
ze_obj = Z_ZIP_P(self);
18701870
if (ze_obj->buffers_cnt) {
1871-
ze_obj->buffers = (char **)safe_erealloc(ze_obj->buffers, sizeof(char *), (ze_obj->buffers_cnt+1), 0);
1871+
ze_obj->buffers = safe_erealloc(ze_obj->buffers, sizeof(*ze_obj->buffers), (ze_obj->buffers_cnt + 1), 0);
18721872
pos = ze_obj->buffers_cnt++;
18731873
} else {
1874-
ze_obj->buffers = (char **)emalloc(sizeof(char *));
1874+
ze_obj->buffers = emalloc(sizeof(*ze_obj->buffers));
18751875
ze_obj->buffers_cnt++;
18761876
pos = 0;
18771877
}
1878-
ze_obj->buffers[pos] = (char *)safe_emalloc(ZSTR_LEN(buffer), 1, 1);
1879-
memcpy(ze_obj->buffers[pos], ZSTR_VAL(buffer), ZSTR_LEN(buffer) + 1);
1878+
ze_obj->buffers[pos] = zend_string_copy(buffer);
18801879

1881-
zs = zip_source_buffer(intern, ze_obj->buffers[pos], ZSTR_LEN(buffer), 0);
1880+
zs = zip_source_buffer(intern, ZSTR_VAL(buffer), ZSTR_LEN(buffer), 0);
18821881

18831882
if (zs == NULL) {
18841883
RETURN_FALSE;

ext/zip/php_zip.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ typedef struct _ze_zip_read_rsrc {
6868
/* Extends zend object */
6969
typedef struct _ze_zip_object {
7070
struct zip *za;
71-
char **buffers;
71+
zend_string **buffers;
7272
HashTable *prop_handler;
7373
char *filename;
7474
int filename_len;

0 commit comments

Comments
 (0)