From: Greg Beaver Date: Fri, 8 Feb 2008 05:57:40 +0000 (+0000) Subject: fix issues in opendir() with empty directories within a phar archive, port filterpara... X-Git-Tag: RELEASE_2_0_0a1~565 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=19df8a4d7f8964426679ae5162f6954aea957347;p=php fix issues in opendir() with empty directories within a phar archive, port filterparams fix to tar.c --- diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index f52c1b2ef4..25a904160e 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -221,6 +221,14 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(manifest, &key, &keylen, &unused, 0, NULL)) { break; } + if (keylen <= dirlen) { + if (keylen < dirlen || !strncmp(key, dir, dirlen)) { + if (SUCCESS != zend_hash_move_forward(manifest)) { + break; + } + continue; + } + } if (*dir == '/') { /* root directory */ if (NULL != (found = (char *) memchr(key, '/', keylen))) { @@ -286,8 +294,7 @@ PHAR_ADD_ENTRY: return php_stream_alloc(&phar_dir_ops, data, NULL, "r"); } else { efree(dir); - FREE_HASHTABLE(data); - return NULL; + return php_stream_alloc(&phar_dir_ops, data, NULL, "r"); } } /* }}}*/ @@ -304,7 +311,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char uint keylen; ulong unused; phar_archive_data *phar; - phar_entry_info *entry; + phar_entry_info *entry = NULL; uint host_len; if ((resource = phar_open_url(wrapper, path, mode, options TSRMLS_CC)) == NULL) { @@ -365,20 +372,26 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char php_url_free(resource); return NULL; } - if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry)) { + if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry) && !entry->is_dir) { php_url_free(resource); return NULL; + } else if (entry && entry->is_dir) { + internal_file = estrdup(internal_file); + php_url_free(resource); + return phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC); } else { + int i_len = strlen(internal_file); + /* search for directory */ zend_hash_internal_pointer_reset(&phar->manifest); while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) { if (HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex( &phar->manifest, &key, &keylen, &unused, 0, NULL)) { - if (0 == memcmp(key, internal_file, strlen(internal_file))) { + if (keylen > i_len && 0 == memcmp(key, internal_file, i_len)) { /* directory found */ internal_file = estrndup(internal_file, - strlen(internal_file)); + i_len); php_url_free(resource); return phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC); } diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 999820eb02..d708c0f517 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -601,12 +601,19 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, char **er zval filterparams; array_init(&filterparams); + /* ext/zlib zval_dtors a separated zval, so we have to make sure it doesn't destroy ours */ +#if PHP_VERSION_ID < 50300 + filterparams->refcount = 26; +#else + Z_SET_REFCOUNT(filterparams, 26); +#endif /* this is defined in zlib's zconf.h */ #ifndef MAX_WBITS #define MAX_WBITS 15 #endif add_assoc_long(&filterparams, "window", MAX_WBITS + 16); filter = php_stream_filter_create("zlib.deflate", &filterparams, php_stream_is_persistent(phar->fp) TSRMLS_CC); + zval_dtor(&filterparams); if (!filter) { /* copy contents uncompressed rather than lose them */ php_stream_copy_to_stream(newfile, phar->fp, PHP_STREAM_COPY_ALL);