@@ -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 }
263225PHAR_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