Skip to content

Commit 1f14d58

Browse files
committed
ext/phar: Remove unnecessary memory duplication for phar_make_dirstream()
And also pass in the known string length
1 parent b581e8e commit 1f14d58

File tree

1 file changed

+16
-20
lines changed

1 file changed

+16
-20
lines changed

Diff for: ext/phar/dirstream.c

+16-20
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,9 @@ static int phar_compare_dir_name(Bucket *f, Bucket *s) /* {{{ */
150150
* files in a phar and retrieving its relative path. From this, construct
151151
* a list of files/directories that are "in" the directory represented by dir
152152
*/
153-
static php_stream *phar_make_dirstream(char *dir, const HashTable *manifest) /* {{{ */
153+
static php_stream *phar_make_dirstream(const char *dir, size_t dirlen, const HashTable *manifest) /* {{{ */
154154
{
155155
HashTable *data;
156-
size_t dirlen = strlen(dir);
157156
char *entry;
158157

159158
ALLOC_HASHTABLE(data);
@@ -162,7 +161,6 @@ static php_stream *phar_make_dirstream(char *dir, const HashTable *manifest) /*
162161
if ((*dir == '/' && dirlen == 1 && (manifest->nNumOfElements == 0)) || (dirlen >= sizeof(".phar")-1 && !memcmp(dir, ".phar", sizeof(".phar")-1))) {
163162
/* make empty root directory for empty phar */
164163
/* make empty directory for .phar magic directory */
165-
efree(dir);
166164
return php_stream_alloc(&phar_dir_ops, data, NULL, "r");
167165
}
168166

@@ -240,11 +238,9 @@ static php_stream *phar_make_dirstream(char *dir, const HashTable *manifest) /*
240238
} ZEND_HASH_FOREACH_END();
241239

242240
if (FAILURE != zend_hash_has_more_elements(data)) {
243-
efree(dir);
244241
zend_hash_sort(data, phar_compare_dir_name, 0);
245242
return php_stream_alloc(&phar_dir_ops, data, NULL, "r");
246243
} else {
247-
efree(dir);
248244
return php_stream_alloc(&phar_dir_ops, data, NULL, "r");
249245
}
250246
}
@@ -256,10 +252,8 @@ static php_stream *phar_make_dirstream(char *dir, const HashTable *manifest) /*
256252
php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) /* {{{ */
257253
{
258254
php_url *resource = NULL;
259-
php_stream *ret;
260-
char *internal_file, *error;
255+
char *error;
261256
phar_archive_data *phar;
262-
phar_entry_info *entry = NULL;
263257

264258
if ((resource = phar_parse_url(wrapper, path, mode, options)) == NULL) {
265259
php_stream_wrapper_log_error(wrapper, options, "phar url \"%s\" is unknown", path);
@@ -285,7 +279,6 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path,
285279
}
286280

287281
phar_request_initialize();
288-
internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */
289282

290283
if (FAILURE == phar_get_archive(&phar, ZSTR_VAL(resource->host), ZSTR_LEN(resource->host), NULL, 0, &error)) {
291284
if (error) {
@@ -302,41 +295,44 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path,
302295
efree(error);
303296
}
304297

305-
if (*internal_file == '\0') {
298+
if (zend_string_equals(resource->path, ZSTR_CHAR('/'))) {
306299
/* root directory requested */
307-
internal_file = estrndup(internal_file - 1, 1);
308-
ret = phar_make_dirstream(internal_file, &phar->manifest);
309300
php_url_free(resource);
310-
return ret;
301+
return phar_make_dirstream("/", strlen("/"), &phar->manifest);
311302
}
312303

313304
if (!HT_IS_INITIALIZED(&phar->manifest)) {
314305
php_url_free(resource);
315306
return NULL;
316307
}
317308

318-
size_t internal_file_len = strlen(internal_file);
319-
if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len)) && !entry->is_dir) {
309+
const char *internal_file = ZSTR_VAL(resource->path) + 1; /* strip leading "/" */
310+
size_t internal_file_len = ZSTR_LEN(resource->path) - 1;
311+
phar_entry_info *entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len);
312+
php_stream *ret;
313+
314+
if (NULL != entry && !entry->is_dir) {
320315
php_url_free(resource);
321316
return NULL;
322317
} else if (entry && entry->is_dir) {
323318
if (entry->is_mounted) {
319+
ret = php_stream_opendir(entry->tmp, options, context);
324320
php_url_free(resource);
325-
return php_stream_opendir(entry->tmp, options, context);
321+
return ret;
326322
}
327-
internal_file = estrdup(internal_file);
323+
ret = phar_make_dirstream(internal_file, internal_file_len, &phar->manifest);
328324
php_url_free(resource);
329-
return phar_make_dirstream(internal_file, &phar->manifest);
325+
return ret;
330326
} else {
331327
zend_string *str_key;
332328

333329
/* search for directory */
334330
ZEND_HASH_MAP_FOREACH_STR_KEY(&phar->manifest, str_key) {
335331
if (zend_string_starts_with_cstr(str_key, internal_file, internal_file_len)) {
336332
/* directory found */
337-
internal_file = estrndup(internal_file, internal_file_len);
333+
ret = phar_make_dirstream(internal_file, internal_file_len, &phar->manifest);
338334
php_url_free(resource);
339-
return phar_make_dirstream(internal_file, &phar->manifest);
335+
return ret;
340336
}
341337
} ZEND_HASH_FOREACH_END();
342338
}

0 commit comments

Comments
 (0)