Skip to content

Commit b581e8e

Browse files
committed
ext/phar: Use HASH_FOREACH macro in phar_make_dirstream()
Also simplify and refactor the inside of the loop
1 parent c74f1be commit b581e8e

File tree

1 file changed

+30
-63
lines changed

1 file changed

+30
-63
lines changed

Diff for: ext/phar/dirstream.c

+30-63
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,6 @@ static int phar_dir_flush(php_stream *stream) /* {{{ */
134134
}
135135
/* }}} */
136136

137-
/**
138-
* add an empty element with a char * key to a hash table, avoiding duplicates
139-
*
140-
* This is used to get a unique listing of virtual directories within a phar,
141-
* for iterating over opendir()ed phar directories.
142-
*/
143-
static int phar_add_empty(HashTable *ht, char *arKey, uint32_t nKeyLength) /* {{{ */
144-
{
145-
zval dummy;
146-
147-
ZVAL_NULL(&dummy);
148-
zend_hash_str_update(ht, arKey, nKeyLength, &dummy);
149-
return SUCCESS;
150-
}
151-
/* }}} */
152-
153137
/**
154138
* Used for sorting directories alphabetically
155139
*/
@@ -166,14 +150,11 @@ static int phar_compare_dir_name(Bucket *f, Bucket *s) /* {{{ */
166150
* files in a phar and retrieving its relative path. From this, construct
167151
* a list of files/directories that are "in" the directory represented by dir
168152
*/
169-
static php_stream *phar_make_dirstream(char *dir, HashTable *manifest) /* {{{ */
153+
static php_stream *phar_make_dirstream(char *dir, const HashTable *manifest) /* {{{ */
170154
{
171155
HashTable *data;
172156
size_t dirlen = strlen(dir);
173-
char *entry, *found, *save;
174-
zend_string *str_key;
175-
size_t keylen;
176-
zend_ulong unused;
157+
char *entry;
177158

178159
ALLOC_HASHTABLE(data);
179160
zend_hash_init(data, 64, NULL, NULL, 0);
@@ -185,92 +166,78 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest) /* {{{ */
185166
return php_stream_alloc(&phar_dir_ops, data, NULL, "r");
186167
}
187168

188-
zend_hash_internal_pointer_reset(manifest);
189-
190-
while (FAILURE != zend_hash_has_more_elements(manifest)) {
191-
if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key(manifest, &str_key, &unused)) {
192-
break;
193-
}
194-
195-
keylen = ZSTR_LEN(str_key);
169+
zend_string *str_key;
170+
ZEND_HASH_MAP_FOREACH_STR_KEY(manifest, str_key) {
171+
size_t keylen = ZSTR_LEN(str_key);
196172
if (keylen <= dirlen) {
197173
if (keylen == 0 || keylen < dirlen || !strncmp(ZSTR_VAL(str_key), dir, dirlen)) {
198-
if (SUCCESS != zend_hash_move_forward(manifest)) {
199-
break;
200-
}
201174
continue;
202175
}
203176
}
204177

205178
if (*dir == '/') {
206179
/* root directory */
207-
if (keylen >= sizeof(".phar")-1 && !memcmp(ZSTR_VAL(str_key), ".phar", sizeof(".phar")-1)) {
180+
if (zend_string_starts_with_literal(str_key, ".phar")) {
208181
/* do not add any magic entries to this directory */
209-
if (SUCCESS != zend_hash_move_forward(manifest)) {
210-
break;
211-
}
212182
continue;
213183
}
214184

215-
if (NULL != (found = (char *) memchr(ZSTR_VAL(str_key), '/', keylen))) {
185+
const char *has_slash = memchr(ZSTR_VAL(str_key), '/', keylen);
186+
if (has_slash) {
216187
/* the entry has a path separator and is a subdirectory */
217-
entry = (char *) safe_emalloc(found - ZSTR_VAL(str_key), 1, 1);
218-
memcpy(entry, ZSTR_VAL(str_key), found - ZSTR_VAL(str_key));
219-
keylen = found - ZSTR_VAL(str_key);
220-
entry[keylen] = '\0';
221-
} else {
222-
entry = (char *) safe_emalloc(keylen, 1, 1);
223-
memcpy(entry, ZSTR_VAL(str_key), keylen);
224-
entry[keylen] = '\0';
188+
keylen = has_slash - ZSTR_VAL(str_key);
225189
}
190+
entry = safe_emalloc(keylen, 1, 1);
191+
memcpy(entry, ZSTR_VAL(str_key), keylen);
192+
entry[keylen] = '\0';
226193

227194
goto PHAR_ADD_ENTRY;
228195
} else {
229196
if (0 != memcmp(ZSTR_VAL(str_key), dir, dirlen)) {
230197
/* entry in directory not found */
231-
if (SUCCESS != zend_hash_move_forward(manifest)) {
232-
break;
233-
}
234198
continue;
235199
} else {
236200
if (ZSTR_VAL(str_key)[dirlen] != '/') {
237-
if (SUCCESS != zend_hash_move_forward(manifest)) {
238-
break;
239-
}
240201
continue;
241202
}
242203
}
243204
}
244205

245-
save = ZSTR_VAL(str_key);
206+
const char *save = ZSTR_VAL(str_key);
246207
save += dirlen + 1; /* seek to just past the path separator */
247208

248-
if (NULL != (found = (char *) memchr(save, '/', keylen - dirlen - 1))) {
209+
const char *has_slash = memchr(save, '/', keylen - dirlen - 1);
210+
if (has_slash) {
249211
/* is subdirectory */
250212
save -= dirlen + 1;
251-
entry = (char *) safe_emalloc(found - save + dirlen, 1, 1);
252-
memcpy(entry, save + dirlen + 1, found - save - dirlen - 1);
253-
keylen = found - save - dirlen - 1;
213+
entry = safe_emalloc(has_slash - save + dirlen, 1, 1);
214+
memcpy(entry, save + dirlen + 1, has_slash - save - dirlen - 1);
215+
keylen = has_slash - save - dirlen - 1;
254216
entry[keylen] = '\0';
255217
} else {
256218
/* is file */
257219
save -= dirlen + 1;
258-
entry = (char *) safe_emalloc(keylen - dirlen, 1, 1);
220+
entry = safe_emalloc(keylen - dirlen, 1, 1);
259221
memcpy(entry, save + dirlen + 1, keylen - dirlen - 1);
260222
entry[keylen - dirlen - 1] = '\0';
261223
keylen = keylen - dirlen - 1;
262224
}
263225
PHAR_ADD_ENTRY:
264226
if (keylen) {
265-
phar_add_empty(data, entry, keylen);
227+
/**
228+
* Add an empty element to avoid duplicates
229+
*
230+
* This is used to get a unique listing of virtual directories within a phar,
231+
* for iterating over opendir()ed phar directories.
232+
*/
233+
zval dummy;
234+
235+
ZVAL_NULL(&dummy);
236+
zend_hash_str_update(data, entry, keylen, &dummy);
266237
}
267238

268239
efree(entry);
269-
270-
if (SUCCESS != zend_hash_move_forward(manifest)) {
271-
break;
272-
}
273-
}
240+
} ZEND_HASH_FOREACH_END();
274241

275242
if (FAILURE != zend_hash_has_more_elements(data)) {
276243
efree(dir);

0 commit comments

Comments
 (0)