@@ -134,22 +134,6 @@ static int phar_dir_flush(php_stream *stream) /* {{{ */
134
134
}
135
135
/* }}} */
136
136
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
-
153
137
/**
154
138
* Used for sorting directories alphabetically
155
139
*/
@@ -166,14 +150,11 @@ static int phar_compare_dir_name(Bucket *f, Bucket *s) /* {{{ */
166
150
* files in a phar and retrieving its relative path. From this, construct
167
151
* a list of files/directories that are "in" the directory represented by dir
168
152
*/
169
- static php_stream * phar_make_dirstream (char * dir , HashTable * manifest ) /* {{{ */
153
+ static php_stream * phar_make_dirstream (char * dir , const HashTable * manifest ) /* {{{ */
170
154
{
171
155
HashTable * data ;
172
156
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 ;
177
158
178
159
ALLOC_HASHTABLE (data );
179
160
zend_hash_init (data , 64 , NULL , NULL , 0 );
@@ -185,92 +166,78 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest) /* {{{ */
185
166
return php_stream_alloc (& phar_dir_ops , data , NULL , "r" );
186
167
}
187
168
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 );
196
172
if (keylen <= dirlen ) {
197
173
if (keylen == 0 || keylen < dirlen || !strncmp (ZSTR_VAL (str_key ), dir , dirlen )) {
198
- if (SUCCESS != zend_hash_move_forward (manifest )) {
199
- break ;
200
- }
201
174
continue ;
202
175
}
203
176
}
204
177
205
178
if (* dir == '/' ) {
206
179
/* 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" )) {
208
181
/* do not add any magic entries to this directory */
209
- if (SUCCESS != zend_hash_move_forward (manifest )) {
210
- break ;
211
- }
212
182
continue ;
213
183
}
214
184
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 ) {
216
187
/* 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 );
225
189
}
190
+ entry = safe_emalloc (keylen , 1 , 1 );
191
+ memcpy (entry , ZSTR_VAL (str_key ), keylen );
192
+ entry [keylen ] = '\0' ;
226
193
227
194
goto PHAR_ADD_ENTRY ;
228
195
} else {
229
196
if (0 != memcmp (ZSTR_VAL (str_key ), dir , dirlen )) {
230
197
/* entry in directory not found */
231
- if (SUCCESS != zend_hash_move_forward (manifest )) {
232
- break ;
233
- }
234
198
continue ;
235
199
} else {
236
200
if (ZSTR_VAL (str_key )[dirlen ] != '/' ) {
237
- if (SUCCESS != zend_hash_move_forward (manifest )) {
238
- break ;
239
- }
240
201
continue ;
241
202
}
242
203
}
243
204
}
244
205
245
- save = ZSTR_VAL (str_key );
206
+ const char * save = ZSTR_VAL (str_key );
246
207
save += dirlen + 1 ; /* seek to just past the path separator */
247
208
248
- if (NULL != (found = (char * ) memchr (save , '/' , keylen - dirlen - 1 ))) {
209
+ const char * has_slash = memchr (save , '/' , keylen - dirlen - 1 );
210
+ if (has_slash ) {
249
211
/* is subdirectory */
250
212
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 ;
254
216
entry [keylen ] = '\0' ;
255
217
} else {
256
218
/* is file */
257
219
save -= dirlen + 1 ;
258
- entry = ( char * ) safe_emalloc (keylen - dirlen , 1 , 1 );
220
+ entry = safe_emalloc (keylen - dirlen , 1 , 1 );
259
221
memcpy (entry , save + dirlen + 1 , keylen - dirlen - 1 );
260
222
entry [keylen - dirlen - 1 ] = '\0' ;
261
223
keylen = keylen - dirlen - 1 ;
262
224
}
263
225
PHAR_ADD_ENTRY :
264
226
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 );
266
237
}
267
238
268
239
efree (entry );
269
-
270
- if (SUCCESS != zend_hash_move_forward (manifest )) {
271
- break ;
272
- }
273
- }
240
+ } ZEND_HASH_FOREACH_END ();
274
241
275
242
if (FAILURE != zend_hash_has_more_elements (data )) {
276
243
efree (dir );
0 commit comments