]> granicus.if.org Git - php/commitdiff
Support for ext/phar (incomplete)
authorDmitry Stogov <dmitry@zend.com>
Thu, 8 May 2014 14:30:07 +0000 (18:30 +0400)
committerDmitry Stogov <dmitry@zend.com>
Thu, 8 May 2014 14:30:07 +0000 (18:30 +0400)
ext/phar/dirstream.c
ext/phar/func_interceptors.c
ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/stream.c
ext/phar/tar.c
ext/phar/util.c
ext/phar/zip.c

index c2a2b7d7f9472c14c7445860b1f1a0a1515dc95f..d24a4c76da15396d19a095c91ba7c0808cf385c7 100644 (file)
@@ -94,23 +94,22 @@ static size_t phar_dir_read(php_stream *stream, char *buf, size_t count TSRMLS_D
 {
        size_t to_read;
        HashTable *data = (HashTable *)stream->abstract;
-       char *str_key;
-       uint keylen;
+       zend_string *str_key;
        ulong unused;
 
-       if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(data, &str_key, &keylen, &unused, 0, NULL)) {
+       if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(data, &str_key, &unused, 0, &data->nInternalPointer)) {
                return 0;
        }
 
        zend_hash_move_forward(data);
-       to_read = MIN(keylen, count);
+       to_read = MIN(str_key->len, count);
 
-       if (to_read == 0 || count < keylen) {
+       if (to_read == 0 || count < str_key->len) {
                return 0;
        }
 
        memset(buf, 0, sizeof(php_stream_dirent));
-       memcpy(((php_stream_dirent *) buf)->d_name, str_key, to_read);
+       memcpy(((php_stream_dirent *) buf)->d_name, str_key->val, to_read);
        ((php_stream_dirent *) buf)->d_name[to_read + 1] = '\0';
 
        return sizeof(php_stream_dirent);
@@ -143,9 +142,10 @@ static int phar_dir_flush(php_stream *stream TSRMLS_DC) /* {{{ */
  */
 static int phar_add_empty(HashTable *ht, char *arKey, uint nKeyLength)  /* {{{ */
 {
-       void *dummy = (char *) 1;
+       zval dummy;
 
-       return zend_hash_update(ht, arKey, nKeyLength, (void *) &dummy, sizeof(void *), NULL);
+       ZVAL_NULL(&dummy);
+       return (zend_hash_str_update(ht, arKey, nKeyLength, &dummy) != NULL) ? SUCCESS : FAILURE;
 }
 /* }}} */
 
@@ -160,7 +160,7 @@ static int phar_compare_dir_name(const void *a, const void *b TSRMLS_DC)  /* {{{
 
        f = (Bucket *) a;
        s = (Bucket *) b;
-       result = zend_binary_strcmp(f->arKey, f->nKeyLength, s->arKey, s->nKeyLength);
+       result = zend_binary_strcmp(f->key->val, f->key->len, s->key->val, s->key->len);
 
        if (result < 0) {
                return -1;
@@ -181,7 +181,8 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
 {
        HashTable *data;
        int dirlen = strlen(dir);
-       char *entry, *found, *save, *str_key;
+       char *entry, *found, *save;
+       zend_string *str_key;
        uint keylen;
        ulong unused;
 
@@ -198,12 +199,13 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
        zend_hash_internal_pointer_reset(manifest);
 
        while (FAILURE != zend_hash_has_more_elements(manifest)) {
-               if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(manifest, &str_key, &keylen, &unused, 0, NULL)) {
+               if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(manifest, &str_key, &unused, 0, &manifest->nInternalPointer)) {
                        break;
                }
 
+               keylen = str_key->len;
                if (keylen <= (uint)dirlen) {
-                       if (keylen < (uint)dirlen || !strncmp(str_key, dir, dirlen)) {
+                       if (keylen < (uint)dirlen || !strncmp(str_key->val, dir, dirlen)) {
                                if (SUCCESS != zend_hash_move_forward(manifest)) {
                                        break;
                                }
@@ -213,7 +215,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
 
                if (*dir == '/') {
                        /* root directory */
-                       if (keylen >= sizeof(".phar")-1 && !memcmp(str_key, ".phar", sizeof(".phar")-1)) {
+                       if (keylen >= sizeof(".phar")-1 && !memcmp(str_key->val, ".phar", sizeof(".phar")-1)) {
                                /* do not add any magic entries to this directory */
                                if (SUCCESS != zend_hash_move_forward(manifest)) {
                                        break;
@@ -221,28 +223,28 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
                                continue;
                        }
 
-                       if (NULL != (found = (char *) memchr(str_key, '/', keylen))) {
+                       if (NULL != (found = (char *) memchr(str_key->val, '/', keylen))) {
                                /* the entry has a path separator and is a subdirectory */
-                               entry = (char *) safe_emalloc(found - str_key, 1, 1);
-                               memcpy(entry, str_key, found - str_key);
-                               keylen = found - str_key;
+                               entry = (char *) safe_emalloc(found - str_key->val, 1, 1);
+                               memcpy(entry, str_key->val, found - str_key->val);
+                               keylen = found - str_key->val;
                                entry[keylen] = '\0';
                        } else {
                                entry = (char *) safe_emalloc(keylen, 1, 1);
-                               memcpy(entry, str_key, keylen);
+                               memcpy(entry, str_key->val, keylen);
                                entry[keylen] = '\0';
                        }
 
                        goto PHAR_ADD_ENTRY;
                } else {
-                       if (0 != memcmp(str_key, dir, dirlen)) {
+                       if (0 != memcmp(str_key->val, dir, dirlen)) {
                                /* entry in directory not found */
                                if (SUCCESS != zend_hash_move_forward(manifest)) {
                                        break;
                                }
                                continue;
                        } else {
-                               if (str_key[dirlen] != '/') {
+                               if (str_key->val[dirlen] != '/') {
                                        if (SUCCESS != zend_hash_move_forward(manifest)) {
                                                break;
                                        }
@@ -251,7 +253,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
                        }
                }
 
-               save = str_key;
+               save = str_key->val;
                save += dirlen + 1; /* seek to just past the path separator */
 
                if (NULL != (found = (char *) memchr(save, '/', keylen - dirlen - 1))) {
@@ -302,8 +304,8 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path,
 {
        php_url *resource = NULL;
        php_stream *ret;
-       char *internal_file, *error, *str_key;
-       uint keylen;
+       char *internal_file, *error;
+       zend_string *str_key;
        ulong unused;
        phar_archive_data *phar;
        phar_entry_info *entry = NULL;
@@ -364,7 +366,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path,
                return NULL;
        }
 
-       if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry) && !entry->is_dir) {
+       if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, strlen(internal_file))) && !entry->is_dir) {
                php_url_free(resource);
                return NULL;
        } else if (entry && entry->is_dir) {
@@ -383,8 +385,8 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path,
                while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
                        if (HASH_KEY_NON_EXISTENT != 
                                        zend_hash_get_current_key_ex(
-                                               &phar->manifest, &str_key, &keylen, &unused, 0, NULL)) {
-                               if (keylen > (uint)i_len && 0 == memcmp(str_key, internal_file, i_len)) {
+                                               &phar->manifest, &str_key, &unused, 0, &phar->manifest.nInternalPointer)) {
+                               if (str_key->len > (uint)i_len && 0 == memcmp(str_key->val, internal_file, i_len)) {
                                        /* directory found */
                                        internal_file = estrndup(internal_file,
                                                        i_len);
@@ -515,7 +517,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo
        entry.flags = PHAR_ENT_PERM_DEF_DIR;
        entry.old_flags = PHAR_ENT_PERM_DEF_DIR;
 
-       if (SUCCESS != zend_hash_add(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+       if (NULL == zend_hash_str_add_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", adding to manifest failed", entry.filename, phar->fname);
                efree(error);
                efree(entry.filename);
@@ -526,7 +528,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo
 
        if (error) {
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", entry.filename, phar->fname, error);
-               zend_hash_del(&phar->manifest, entry.filename, entry.filename_len);
+               zend_hash_str_del(&phar->manifest, entry.filename, entry.filename_len);
                efree(error);
                return 0;
        }
@@ -547,8 +549,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
        int arch_len, entry_len;
        php_url *resource = NULL;
        uint host_len;
-       char *str_key;
-       uint key_len;
+       zend_string *str_key;
        ulong unused;
        uint path_len;
 
@@ -611,12 +612,12 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
 
        if (!entry->is_deleted) {
                for (zend_hash_internal_pointer_reset(&phar->manifest);
-                       HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->manifest, &str_key, &key_len, &unused, 0, NULL);
+                       HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->manifest, &str_key, &unused, 0, &phar->manifest.nInternalPointer);
                        zend_hash_move_forward(&phar->manifest)
                ) {
-                       if (key_len > path_len && 
-                               memcmp(str_key, resource->path+1, path_len) == 0 && 
-                               IS_SLASH(str_key[path_len])) {
+                       if (str_key->len > path_len && 
+                               memcmp(str_key->val, resource->path+1, path_len) == 0 && 
+                               IS_SLASH(str_key->val[path_len])) {
                                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty");
                                if (entry->is_temp_dir) {
                                        efree(entry->filename);
@@ -628,12 +629,12 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
                }
 
                for (zend_hash_internal_pointer_reset(&phar->virtual_dirs);
-                       HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &str_key, &key_len, &unused, 0, NULL);
+                       HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &str_key, &unused, 0, &phar->virtual_dirs.nInternalPointer);
                        zend_hash_move_forward(&phar->virtual_dirs)) {
        
-                       if (key_len > path_len && 
-                               memcmp(str_key, resource->path+1, path_len) == 0 && 
-                               IS_SLASH(str_key[path_len])) {
+                       if (str_key->len > path_len && 
+                               memcmp(str_key->val, resource->path+1, path_len) == 0 && 
+                               IS_SLASH(str_key->val[path_len])) {
                                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty");
                                if (entry->is_temp_dir) {
                                        efree(entry->filename);
@@ -646,7 +647,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
        }
 
        if (entry->is_temp_dir) {
-               zend_hash_del(&phar->virtual_dirs, resource->path+1, path_len);
+               zend_hash_str_del(&phar->virtual_dirs, resource->path+1, path_len);
                efree(entry->filename);
                efree(entry);
        } else {
index 5080ddf7c802edbad03eedf76732015440797d41..392f7d73ab162b104c20dd3ad25d7c63b2923afb 100644 (file)
@@ -95,10 +95,9 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */
 {
        char *filename;
        int filename_len;
-       char *contents;
+       zend_string *contents;
        zend_bool use_include_path = 0;
        php_stream *stream;
-       int len;
        long offset = -1;
        long maxlen = PHP_STREAM_COPY_ALL;
        zval *zcontext = NULL;
@@ -160,7 +159,7 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */
                        } else {
                                entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                                if (entry[0] == '/') {
-                                       if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
+                                       if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
                                                /* this file is not in the phar, use the original path */
 notfound:
                                                efree(arch);
@@ -168,7 +167,7 @@ notfound:
                                                goto skip_phar;
                                        }
                                } else {
-                                       if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
+                                       if (!zend_hash_str_exists(&(phar->manifest), entry, entry_len)) {
                                                goto notfound;
                                        }
                                }
@@ -202,10 +201,11 @@ phar_it:
                        }
 
                        /* uses mmap if possible */
-                       if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
-                               RETVAL_STRINGL(contents, len, 0);
-                               efree(contents);
-                       } else if (len == 0) {
+                       contents = php_stream_copy_to_mem(stream, maxlen, 0);
+                       if (contents && contents->len > 0) {
+                               RETVAL_STR(contents);
+                       } else if (contents) {
+                               STR_RELEASE(contents);
                                RETVAL_EMPTY_STRING();
                        } else {
                                RETVAL_FALSE;
@@ -277,7 +277,7 @@ PHAR_FUNC(phar_readfile) /* {{{ */
                } else {
                        entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                        if (entry[0] == '/') {
-                               if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
+                               if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
                                        /* this file is not in the phar, use the original path */
 notfound:
                                        efree(entry);
@@ -285,7 +285,7 @@ notfound:
                                        goto skip_phar;
                                }
                        } else {
-                               if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
+                               if (!zend_hash_str_exists(&(phar->manifest), entry, entry_len)) {
                                        goto notfound;
                                }
                        }
@@ -373,7 +373,7 @@ PHAR_FUNC(phar_fopen) /* {{{ */
                } else {
                        entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                        if (entry[0] == '/') {
-                               if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
+                               if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
                                        /* this file is not in the phar, use the original path */
 notfound:
                                        efree(entry);
@@ -381,7 +381,7 @@ notfound:
                                        goto skip_phar;
                                }
                        } else {
-                               if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
+                               if (!zend_hash_str_exists(&(phar->manifest), entry, entry_len)) {
                                        /* this file is not in the phar, use the original path */
                                        goto notfound;
                                }
@@ -404,7 +404,7 @@ notfound:
                }
                php_stream_to_zval(stream, return_value);
                if (zcontext) {
-                       zend_list_addref(Z_RESVAL_P(zcontext));
+                       Z_ADDREF_P(zcontext);
                }
                return;
        }
@@ -435,8 +435,8 @@ skip_phar:
  */
 static void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value TSRMLS_DC)
 {
-       zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
-                *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
+       zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev,
+                stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks;
        int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
        char *stat_sb_names[13] = {
                "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
@@ -506,14 +506,14 @@ static void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value T
 #endif
        case FS_TYPE:
                if (S_ISLNK(stat_sb->st_mode)) {
-                       RETURN_STRING("link", 1);
+                       RETURN_STRING("link");
                }
                switch(stat_sb->st_mode & S_IFMT) {
-               case S_IFDIR: RETURN_STRING("dir", 1);
-               case S_IFREG: RETURN_STRING("file", 1);
+               case S_IFDIR: RETURN_STRING("dir");
+               case S_IFREG: RETURN_STRING("file");
                }
                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%u)", stat_sb->st_mode & S_IFMT);
-               RETURN_STRING("unknown", 1);
+               RETURN_STRING("unknown");
        case FS_IS_W:
                RETURN_BOOL((stat_sb->st_mode & wmask) != 0);
        case FS_IS_R:
@@ -533,67 +533,67 @@ static void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value T
        case FS_STAT:
                array_init(return_value);
 
-               MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev);
-               MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino);
-               MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode);
-               MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink);
-               MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid);
-               MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid);
+               ZVAL_LONG(&stat_dev, stat_sb->st_dev);
+               ZVAL_LONG(&stat_ino, stat_sb->st_ino);
+               ZVAL_LONG(&stat_mode, stat_sb->st_mode);
+               ZVAL_LONG(&stat_nlink, stat_sb->st_nlink);
+               ZVAL_LONG(&stat_uid, stat_sb->st_uid);
+               ZVAL_LONG(&stat_gid, stat_sb->st_gid);
 #ifdef HAVE_ST_RDEV
-               MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev);
+               ZVAL_LONG(&stat_rdev, stat_sb->st_rdev);
 #else
-               MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
+               ZVAL_LONG(&stat_rdev, -1);
 #endif
-               MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);
+               ZVAL_LONG(&stat_size, stat_sb->st_size);
 #ifdef NETWARE
-               MAKE_LONG_ZVAL_INCREF(stat_atime, (stat_sb->st_atime).tv_sec);
-               MAKE_LONG_ZVAL_INCREF(stat_mtime, (stat_sb->st_mtime).tv_sec);
-               MAKE_LONG_ZVAL_INCREF(stat_ctime, (stat_sb->st_ctime).tv_sec);
+               ZVAL_LONG(&stat_atime, (stat_sb->st_atime).tv_sec);
+               ZVAL_LONG(&stat_mtime, (stat_sb->st_mtime).tv_sec);
+               ZVAL_LONG(&stat_ctime, (stat_sb->st_ctime).tv_sec);
 #else
-               MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime);
-               MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime);
-               MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime);
+               ZVAL_LONG(&stat_atime, stat_sb->st_atime);
+               ZVAL_LONG(&stat_mtime, stat_sb->st_mtime);
+               ZVAL_LONG(&stat_ctime, stat_sb->st_ctime);
 #endif
 #ifdef HAVE_ST_BLKSIZE
-               MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize);
+               ZVAL_LONG(&stat_blksize, stat_sb->st_blksize);
 #else
-               MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
+               ZVAL_LONG(&stat_blksize,-1);
 #endif
 #ifdef HAVE_ST_BLOCKS
-               MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks);
+               ZVAL_LONG(&stat_blocks, stat_sb->st_blocks);
 #else
-               MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
+               ZVAL_LONG(&stat_blocks,-1);
 #endif
                /* Store numeric indexes in propper order */
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);
-
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
-               zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_dev);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_ino);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_mode);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_nlink);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_uid);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_gid);
+
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_rdev);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_size);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_atime);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_mtime);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_ctime);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_blksize);
+               zend_hash_next_index_insert(HASH_OF(return_value), &stat_blocks);
 
                /* Store string indexes referencing the same zval*/
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *) &stat_ino, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *) &stat_uid, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *) &stat_size, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL);
-               zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0]), &stat_dev);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1]), &stat_ino);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2]), &stat_mode);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3]), &stat_nlink);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4]), &stat_uid);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5]), &stat_gid);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6]), &stat_rdev);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7]), &stat_size);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8]), &stat_atime);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9]), &stat_mtime);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10]), &stat_ctime);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11]), &stat_blksize);
+               zend_hash_str_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12]), &stat_blocks);
 
                return;
        }
@@ -647,17 +647,17 @@ static void phar_file_stat(const char *filename, php_stat_len filename_length, i
 splitted:
                        entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
                        if (entry[0] == '/') {
-                               if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) {
+                               if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) {
                                        efree(entry);
                                        goto stat_entry;
                                }
                                goto notfound;
                        }
-                       if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &data)) {
+                       if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) {
                                efree(entry);
                                goto stat_entry;
                        }
-                       if (zend_hash_exists(&(phar->virtual_dirs), entry, entry_len)) {
+                       if (zend_hash_str_exists(&(phar->virtual_dirs), entry, entry_len)) {
                                efree(entry);
                                efree(arch);
                                if (IS_EXISTS_CHECK(type)) {
@@ -691,7 +691,7 @@ notfound:
                                PHAR_G(cwd_len) = 0;
                                /* clean path without cwd */
                                entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
-                               if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) {
+                               if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) {
                                        PHAR_G(cwd) = save;
                                        PHAR_G(cwd_len) = save_len;
                                        efree(entry);
@@ -701,7 +701,7 @@ notfound:
                                        }
                                        goto stat_entry;
                                }
-                               if (zend_hash_exists(&(phar->virtual_dirs), entry + 1, entry_len - 1)) {
+                               if (zend_hash_str_exists(&(phar->virtual_dirs), entry + 1, entry_len - 1)) {
                                        PHAR_G(cwd) = save;
                                        PHAR_G(cwd_len) = save_len;
                                        efree(entry);
@@ -927,7 +927,7 @@ PHAR_FUNC(phar_is_file) /* {{{ */
 
                                entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                                if (entry[0] == '/') {
-                                       if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
+                                       if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) {
                                                /* this file is not in the current directory, use the original path */
 found_it:
                                                efree(entry);
@@ -935,7 +935,7 @@ found_it:
                                                RETURN_BOOL(!etemp->is_dir);
                                        }
                                } else {
-                                       if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) {
+                                       if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) {
                                                goto found_it;
                                        }
                                }
@@ -994,7 +994,7 @@ PHAR_FUNC(phar_is_link) /* {{{ */
 
                                entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                                if (entry[0] == '/') {
-                                       if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
+                                       if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) {
                                                /* this file is not in the current directory, use the original path */
 found_it:
                                                efree(entry);
@@ -1002,7 +1002,7 @@ found_it:
                                                RETURN_BOOL(etemp->link);
                                        }
                                } else {
-                                       if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) {
+                                       if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) {
                                                goto found_it;
                                        }
                                }
@@ -1049,7 +1049,7 @@ void phar_release_functions(TSRMLS_D)
 /* {{{ void phar_intercept_functions_init(TSRMLS_D) */
 #define PHAR_INTERCEPT(func) \
        PHAR_G(orig_##func) = NULL; \
-       if (SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void **)&orig)) { \
+       if (NULL != (orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1))) { \
                PHAR_G(orig_##func) = orig->internal_function.handler; \
                orig->internal_function.handler = phar_##func; \
        }
@@ -1086,7 +1086,7 @@ void phar_intercept_functions_init(TSRMLS_D)
 
 /* {{{ void phar_intercept_functions_shutdown(TSRMLS_D) */
 #define PHAR_RELEASE(func) \
-       if (PHAR_G(orig_##func) && SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void **)&orig)) { \
+       if (PHAR_G(orig_##func) && NULL != (orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1))) { \
                orig->internal_function.handler = PHAR_G(orig_##func); \
        } \
        PHAR_G(orig_##func) = NULL;
index a23c1b89c23f4f666686bed2990964bf446c4867..05a90fc2df42bbb41833bccb656a54fa186fb4be 100644 (file)
@@ -24,7 +24,7 @@
 #include "SAPI.h"
 #include "func_interceptors.h"
 
-static void destroy_phar_data(void *pDest);
+static void destroy_phar_data(zval *zv);
 
 ZEND_DECLARE_MODULE_GLOBALS(phar)
 char *(*phar_save_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
@@ -32,10 +32,10 @@ char *(*phar_save_resolve_path)(const char *filename, int filename_len TSRMLS_DC
 /**
  * set's phar->is_writeable based on the current INI value
  */
-static int phar_set_writeable_bit(void *pDest, void *argument TSRMLS_DC) /* {{{ */
+static int phar_set_writeable_bit(zval *zv, void *argument TSRMLS_DC) /* {{{ */
 {
        zend_bool keep = *(zend_bool *)argument;
-       phar_archive_data *phar = *(phar_archive_data **)pDest;
+       phar_archive_data *phar = (phar_archive_data *)Z_PTR_P(zv);
 
        if (!phar->is_data) {
                phar->is_writeable = !keep;
@@ -115,12 +115,11 @@ static void phar_split_cache_list(TSRMLS_D) /* {{{ */
 
        /* fake request startup */
        PHAR_GLOBALS->request_init = 1;
-       if (zend_hash_init(&EG(regular_list), 0, NULL, NULL, 0) == SUCCESS) {
-               EG(regular_list).nNextFreeElement=1;    /* we don't want resource id 0 */
-       }
+       zend_hash_init(&EG(regular_list), 0, NULL, NULL, 0);
+       EG(regular_list).nNextFreeElement=1;    /* we don't want resource id 0 */
 
-       PHAR_G(has_bz2) = zend_hash_exists(&module_registry, "bz2", sizeof("bz2"));
-       PHAR_G(has_zlib) = zend_hash_exists(&module_registry, "zlib", sizeof("zlib"));
+       PHAR_G(has_bz2) = zend_hash_str_exists(&module_registry, "bz2", sizeof("bz2")-1);
+       PHAR_G(has_zlib) = zend_hash_str_exists(&module_registry, "zlib", sizeof("zlib")-1);
        /* these two are dummies and will be destroyed later */
        zend_hash_init(&cached_phars, sizeof(phar_archive_data*), zend_get_hash_value, destroy_phar_data,  1);
        zend_hash_init(&cached_alias, sizeof(phar_archive_data*), zend_get_hash_value, NULL, 1);
@@ -236,11 +235,11 @@ void phar_destroy_phar_data(phar_archive_data *phar TSRMLS_DC) /* {{{ */
                phar->virtual_dirs.arHash = NULL;
        }
 
-       if (phar->metadata) {
+       if (Z_TYPE(phar->metadata) != IS_UNDEF) {
                if (phar->is_persistent) {
                        if (phar->metadata_len) {
                                /* for zip comments that are strings */
-                               free(phar->metadata);
+                               free(Z_PTR(phar->metadata));
                        } else {
                                zval_internal_ptr_dtor(&phar->metadata);
                        }
@@ -248,7 +247,7 @@ void phar_destroy_phar_data(phar_archive_data *phar TSRMLS_DC) /* {{{ */
                        zval_ptr_dtor(&phar->metadata);
                }
                phar->metadata_len = 0;
-               phar->metadata = 0;
+               ZVAL_UNDEF(&phar->metadata);
        }
 
        if (phar->fp) {
@@ -276,7 +275,7 @@ int phar_archive_delref(phar_archive_data *phar TSRMLS_DC) /* {{{ */
 
        if (--phar->refcount < 0) {
                if (PHAR_GLOBALS->request_done
-               || zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), phar->fname, phar->fname_len) != SUCCESS) {
+               || zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), phar->fname, phar->fname_len) != SUCCESS) {
                        phar_destroy_phar_data(phar TSRMLS_CC);
                }
                return 1;
@@ -297,7 +296,7 @@ int phar_archive_delref(phar_archive_data *phar TSRMLS_DC) /* {{{ */
                if (!zend_hash_num_elements(&phar->manifest)) {
                        /* this is a new phar that has perhaps had an alias/metadata set, but has never
                        been flushed */
-                       if (zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), phar->fname, phar->fname_len) != SUCCESS) {
+                       if (zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), phar->fname, phar->fname_len) != SUCCESS) {
                                phar_destroy_phar_data(phar TSRMLS_CC);
                        }
                        return 1;
@@ -310,9 +309,9 @@ int phar_archive_delref(phar_archive_data *phar TSRMLS_DC) /* {{{ */
 /**
  * Destroy phar's in shutdown, here we don't care about aliases
  */
-static void destroy_phar_data_only(void *pDest) /* {{{ */
+static void destroy_phar_data_only(zval *zv) /* {{{ */
 {
-       phar_archive_data *phar_data = *(phar_archive_data **) pDest;
+       phar_archive_data *phar_data = (phar_archive_data *) Z_PTR_P(zv);
        TSRMLS_FETCH();
 
        if (EG(exception) || --phar_data->refcount < 0) {
@@ -324,18 +323,18 @@ static void destroy_phar_data_only(void *pDest) /* {{{ */
 /**
  * Delete aliases to phar's that got kicked out of the global table
  */
-static int phar_unalias_apply(void *pDest, void *argument TSRMLS_DC) /* {{{ */
+static int phar_unalias_apply(zval *zv, void *argument TSRMLS_DC) /* {{{ */
 {
-       return *(void**)pDest == argument ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_KEEP;
+       return Z_PTR_P(zv) == argument ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_KEEP;
 }
 /* }}} */
 
 /**
  * Delete aliases to phar's that got kicked out of the global table
  */
-static int phar_tmpclose_apply(void *pDest TSRMLS_DC) /* {{{ */
+static int phar_tmpclose_apply(zval *zv TSRMLS_DC) /* {{{ */
 {
-       phar_entry_info *entry = (phar_entry_info *) pDest;
+       phar_entry_info *entry = (phar_entry_info *) Z_PTR_P(zv);
 
        if (entry->fp_type != PHAR_TMP) {
                return ZEND_HASH_APPLY_KEEP;
@@ -353,16 +352,16 @@ static int phar_tmpclose_apply(void *pDest TSRMLS_DC) /* {{{ */
 /**
  * Filename map destructor
  */
-static void destroy_phar_data(void *pDest) /* {{{ */
+static void destroy_phar_data(zval *zv) /* {{{ */
 {
-       phar_archive_data *phar_data = *(phar_archive_data **) pDest;
+       phar_archive_data *phar_data = (phar_archive_data *)Z_PTR_P(zv);
        TSRMLS_FETCH();
 
        if (PHAR_GLOBALS->request_ends) {
                /* first, iterate over the manifest and close all PHAR_TMP entry fp handles,
                this prevents unnecessary unfreed stream resources */
                zend_hash_apply(&(phar_data->manifest), phar_tmpclose_apply TSRMLS_CC);
-               destroy_phar_data_only(pDest);
+               destroy_phar_data_only(zv);
                return;
        }
 
@@ -377,9 +376,9 @@ static void destroy_phar_data(void *pDest) /* {{{ */
 /**
  * destructor for the manifest hash, frees each file's entry
  */
-void destroy_phar_manifest_entry(void *pDest) /* {{{ */
+void destroy_phar_manifest_entry(zval *zv) /* {{{ */
 {
-       phar_entry_info *entry = (phar_entry_info *)pDest;
+       phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv);
        TSRMLS_FETCH();
 
        if (entry->cfp) {
@@ -392,11 +391,11 @@ void destroy_phar_manifest_entry(void *pDest) /* {{{ */
                entry->fp = 0;
        }
 
-       if (entry->metadata) {
+       if (Z_TYPE(entry->metadata) != IS_UNDEF) {
                if (entry->is_persistent) {
                        if (entry->metadata_len) {
                                /* for zip comments that are strings */
-                               free(entry->metadata);
+                               free(Z_PTR(entry->metadata));
                        } else {
                                zval_internal_ptr_dtor(&entry->metadata);
                        }
@@ -404,12 +403,12 @@ void destroy_phar_manifest_entry(void *pDest) /* {{{ */
                        zval_ptr_dtor(&entry->metadata);
                }
                entry->metadata_len = 0;
-               entry->metadata = 0;
+               ZVAL_UNDEF(&entry->metadata);
        }
 
-       if (entry->metadata_str.c) {
+       if (entry->metadata_str.s) {
                smart_str_free(&entry->metadata_str);
-               entry->metadata_str.c = 0;
+               entry->metadata_str.s = NULL;
        }
 
        pefree(entry->filename, entry->is_persistent);
@@ -423,6 +422,8 @@ void destroy_phar_manifest_entry(void *pDest) /* {{{ */
                pefree(entry->tmp, entry->is_persistent);
                entry->tmp = 0;
        }
+
+       pefree(entry, entry->is_persistent);
 }
 /* }}} */
 
@@ -464,7 +465,7 @@ void phar_entry_remove(phar_entry_data *idata, char **error TSRMLS_DC) /* {{{ */
                if (idata->fp && idata->fp != idata->phar->fp && idata->fp != idata->phar->ufp && idata->fp != idata->internal_file->fp) {
                        php_stream_close(idata->fp);
                }
-               zend_hash_del(&idata->phar->manifest, idata->internal_file->filename, idata->internal_file->filename_len);
+               zend_hash_str_del(&idata->phar->manifest, idata->internal_file->filename, idata->internal_file->filename_len);
                idata->phar->refcount--;
                efree(idata);
        } else {
@@ -562,7 +563,7 @@ int phar_open_parsed_phar(char *fname, int fname_len, char *alias, int alias_len
                if (!is_data) {
                        /* prevent any ".phar" without a stub getting through */
                        if (!phar->halt_offset && !phar->is_brandnew && (phar->is_tar || phar->is_zip)) {
-                               if (PHAR_G(readonly) && FAILURE == zend_hash_find(&(phar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1, (void **)&stub)) {
+                               if (PHAR_G(readonly) && NULL == (stub = zend_hash_str_find_ptr(&(phar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1))) {
                                        if (error) {
                                                spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", fname);
                                        }
@@ -601,7 +602,7 @@ int phar_open_parsed_phar(char *fname, int fname_len, char *alias, int alias_len
  * 
  * data is the serialized zval
  */
-int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC) /* {{{ */
+int phar_parse_metadata(char **buffer, zval *metadata, int zip_metadata_len TSRMLS_DC) /* {{{ */
 {
        const unsigned char *p;
        php_uint32 buf_len;
@@ -614,15 +615,14 @@ int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSR
        }
 
        if (buf_len) {
-               ALLOC_ZVAL(*metadata);
-               INIT_ZVAL(**metadata);
+               ZVAL_NULL(metadata);
                p = (const unsigned char*) *buffer;
                PHP_VAR_UNSERIALIZE_INIT(var_hash);
 
                if (!php_var_unserialize(metadata, &p, p + buf_len, &var_hash TSRMLS_CC)) {
                        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
                        zval_ptr_dtor(metadata);
-                       *metadata = NULL;
+                       ZVAL_UNDEF(metadata);
                        return FAILURE;
                }
 
@@ -631,13 +631,13 @@ int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSR
                if (PHAR_G(persist)) {
                        /* lazy init metadata */
                        zval_ptr_dtor(metadata);
-                       *metadata = (zval *) pemalloc(buf_len, 1);
-                       memcpy(*metadata, *buffer, buf_len);
+                       Z_PTR_P(metadata) = pemalloc(buf_len, 1);
+                       memcpy(Z_PTR_P(metadata), *buffer, buf_len);
                        *buffer += buf_len;
                        return SUCCESS;
                }
        } else {
-               *metadata = NULL;
+               ZVAL_UNDEF(metadata);
        }
 
        if (!zip_metadata_len) {
@@ -1129,9 +1129,9 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
                switch (entry.flags & PHAR_ENT_COMPRESSION_MASK) {
                        case PHAR_ENT_COMPRESSED_GZ:
                                if (!PHAR_G(has_zlib)) {
-                                       if (entry.metadata) {
+                                       if (Z_TYPE(entry.metadata) != IS_UNDEF) {
                                                if (entry.is_persistent) {
-                                                       free(entry.metadata);
+                                                       free(Z_PTR(entry.metadata));
                                                } else {
                                                        zval_ptr_dtor(&entry.metadata);
                                                }
@@ -1142,9 +1142,9 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
                                break;
                        case PHAR_ENT_COMPRESSED_BZ2:
                                if (!PHAR_G(has_bz2)) {
-                                       if (entry.metadata) {
+                                       if (Z_TYPE(entry.metadata) != IS_UNDEF) {
                                                if (entry.is_persistent) {
-                                                       free(entry.metadata);
+                                                       free(Z_PTR(entry.metadata));
                                                } else {
                                                        zval_ptr_dtor(&entry.metadata);
                                                }
@@ -1155,9 +1155,9 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
                                break;
                        default:
                                if (entry.uncompressed_filesize != entry.compressed_filesize) {
-                                       if (entry.metadata) {
+                                       if (Z_TYPE(entry.metadata) != IS_UNDEF) {
                                                if (entry.is_persistent) {
-                                                       free(entry.metadata);
+                                                       free(Z_PTR(entry.metadata));
                                                } else {
                                                        zval_ptr_dtor(&entry.metadata);
                                                }
@@ -1172,7 +1172,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
                /* if signature matched, no need to check CRC32 for each file */
                entry.is_crc_checked = (manifest_flags & PHAR_HDR_SIGNATURE ? 1 : 0);
                phar_set_inode(&entry TSRMLS_CC);
-               zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
+               zend_hash_str_add_mem(&mydata->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info));
        }
 
        snprintf(mydata->version, sizeof(mydata->version), "%u.%u.%u", manifest_ver >> 12, (manifest_ver >> 8) & 0xF, (manifest_ver >> 4) & 0xF);
@@ -1202,7 +1202,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
        phar_request_initialize(TSRMLS_C);
 
        if (register_alias) {
-               phar_archive_data **fd_ptr;
+               phar_archive_data *fd_ptr;
 
                mydata->is_temporary_alias = temp_alias;
 
@@ -1212,20 +1212,20 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
                        MAPPHAR_FAIL("Cannot open archive \"%s\", invalid alias");
                }
 
-               if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
-                       if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+               if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len))) {
+                       if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len TSRMLS_CC)) {
                                signature = NULL;
                                fp = NULL;
                                MAPPHAR_FAIL("Cannot open archive \"%s\", alias is already in use by existing archive");
                        }
                }
 
-               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+               zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, mydata);
        } else {
                mydata->is_temporary_alias = 1;
        }
 
-       zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*),  NULL);
+       zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, mydata);
        efree(savebuf);
 
        if (pphar) {
@@ -1283,7 +1283,7 @@ check_file:
 
                if (PHAR_G(readonly) && !(*test)->is_data && ((*test)->is_tar || (*test)->is_zip)) {
                        phar_entry_info *stub;
-                       if (FAILURE == zend_hash_find(&((*test)->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1, (void **)&stub)) {
+                       if (NULL == (stub = zend_hash_str_find_ptr(&((*test)->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1))) {
                                spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", fname);
                                return FAILURE;
                        }
@@ -1410,7 +1410,7 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
        mydata->is_writeable = 1;
        mydata->is_brandnew = 1;
        phar_request_initialize(TSRMLS_C);
-       zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*),  NULL);
+       zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, mydata);
 
        if (is_data) {
                alias = NULL;
@@ -1419,15 +1419,15 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
                /* assume tar format, PharData can specify other */
                mydata->is_tar = 1;
        } else {
-               phar_archive_data **fd_ptr;
+               phar_archive_data *fd_ptr;
 
-               if (alias && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
-                       if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+               if (alias && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len))) {
+                       if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len TSRMLS_CC)) {
                                if (error) {
                                        spprintf(error, 4096, "phar error: phar \"%s\" cannot set alias \"%s\", already in use by another phar archive", mydata->fname, alias);
                                }
 
-                               zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                               zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
 
                                if (pphar) {
                                        *pphar = NULL;
@@ -1442,14 +1442,14 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
        }
 
        if (alias_len && alias) {
-               if (FAILURE == zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL)) {
+               if (NULL == zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, mydata)) {
                        if (options & REPORT_ERRORS) {
                                if (error) {
                                        spprintf(error, 0, "archive \"%s\" cannot be associated with alias \"%s\", already in use", fname, alias);
                                }
                        }
 
-                       zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                       zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
 
                        if (pphar) {
                                *pphar = NULL;
@@ -1743,13 +1743,13 @@ static int phar_analyze_path(const char *fname, const char *ext, int ext_len, in
 #ifdef PHP_WIN32
                phar_unixify_path_separators(realpath, strlen(realpath));
 #endif
-               if (zend_hash_exists(&(PHAR_GLOBALS->phar_fname_map), realpath, strlen(realpath))) {
+               if (zend_hash_str_exists(&(PHAR_GLOBALS->phar_fname_map), realpath, strlen(realpath))) {
                        efree(realpath);
                        efree(filename);
                        return SUCCESS;
                }
 
-               if (PHAR_G(manifest_cached) && zend_hash_exists(&cached_phars, realpath, strlen(realpath))) {
+               if (PHAR_G(manifest_cached) && zend_hash_str_exists(&cached_phars, realpath, strlen(realpath))) {
                        efree(realpath);
                        efree(filename);
                        return SUCCESS;
@@ -1912,13 +1912,13 @@ int phar_detect_phar_fname_ext(const char *filename, int filename_len, const cha
                        *ext_str = NULL;
                        return FAILURE;
                }
-               if (zend_hash_exists(&(PHAR_GLOBALS->phar_alias_map), (char *) filename, pos - filename)) {
+               if (zend_hash_str_exists(&(PHAR_GLOBALS->phar_alias_map), (char *) filename, pos - filename)) {
                        *ext_str = pos;
                        *ext_len = -1;
                        return FAILURE;
                }
 
-               if (PHAR_G(manifest_cached) && zend_hash_exists(&cached_alias, (char *) filename, pos - filename)) {
+               if (PHAR_G(manifest_cached) && zend_hash_str_exists(&cached_alias, (char *) filename, pos - filename)) {
                        *ext_str = pos;
                        *ext_len = -1;
                        return FAILURE;
@@ -1926,71 +1926,70 @@ int phar_detect_phar_fname_ext(const char *filename, int filename_len, const cha
        }
 
        if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)) || PHAR_G(manifest_cached)) {
-               phar_archive_data **pphar;
+               phar_archive_data *pphar;
 
                if (is_complete) {
-                       if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), (char *) filename, filename_len, (void **)&pphar)) {
-                               *ext_str = filename + (filename_len - (*pphar)->ext_len);
+                       if (NULL != (pphar = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), (char *) filename, filename_len))) {
+                               *ext_str = filename + (filename_len - pphar->ext_len);
 woohoo:
-                               *ext_len = (*pphar)->ext_len;
+                               *ext_len = pphar->ext_len;
 
                                if (executable == 2) {
                                        return SUCCESS;
                                }
 
-                               if (executable == 1 && !(*pphar)->is_data) {
+                               if (executable == 1 && !pphar->is_data) {
                                        return SUCCESS;
                                }
 
-                               if (!executable && (*pphar)->is_data) {
+                               if (!executable && pphar->is_data) {
                                        return SUCCESS;
                                }
 
                                return FAILURE;
                        }
 
-                       if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, (char *) filename, filename_len, (void **)&pphar)) {
-                               *ext_str = filename + (filename_len - (*pphar)->ext_len);
+                       if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, (char *) filename, filename_len))) {
+                               *ext_str = filename + (filename_len - pphar->ext_len);
                                goto woohoo;
                        }
                } else {
-                       char *str_key;
-                       uint keylen;
+                       zend_string *str_key;
                        ulong unused;
 
                        for (zend_hash_internal_pointer_reset(&(PHAR_GLOBALS->phar_fname_map));
-                               HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&(PHAR_GLOBALS->phar_fname_map), &str_key, &keylen, &unused, 0, NULL);
+                               HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&(PHAR_GLOBALS->phar_fname_map), &str_key, &unused, 0, &PHAR_GLOBALS->phar_fname_map.nInternalPointer);
                                zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map))
                        ) {
-                               if (keylen > (uint) filename_len) {
+                               if (str_key->len > (uint) filename_len) {
                                        continue;
                                }
 
-                               if (!memcmp(filename, str_key, keylen) && ((uint)filename_len == keylen
-                                       || filename[keylen] == '/' || filename[keylen] == '\0')) {
-                                       if (FAILURE == zend_hash_get_current_data(&(PHAR_GLOBALS->phar_fname_map), (void **) &pphar)) {
+                               if (!memcmp(filename, str_key->val, str_key->len) && ((uint)filename_len == str_key->len
+                                       || filename[str_key->len] == '/' || filename[str_key->len] == '\0')) {
+                                       if (NULL == (pphar = zend_hash_get_current_data_ptr(&(PHAR_GLOBALS->phar_fname_map)))) {
                                                break;
                                        }
-                                       *ext_str = filename + (keylen - (*pphar)->ext_len);
+                                       *ext_str = filename + (str_key->len - pphar->ext_len);
                                        goto woohoo;
                                }
                        }
 
                        if (PHAR_G(manifest_cached)) {
                                for (zend_hash_internal_pointer_reset(&cached_phars);
-                                       HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&cached_phars, &str_key, &keylen, &unused, 0, NULL);
+                                       HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&cached_phars, &str_key, &unused, 0, &cached_phars.nInternalPointer);
                                        zend_hash_move_forward(&cached_phars)
                                ) {
-                                       if (keylen > (uint) filename_len) {
+                                       if (str_key->len > (uint) filename_len) {
                                                continue;
                                        }
 
-                                       if (!memcmp(filename, str_key, keylen) && ((uint)filename_len == keylen
-                                               || filename[keylen] == '/' || filename[keylen] == '\0')) {
-                                               if (FAILURE == zend_hash_get_current_data(&cached_phars, (void **) &pphar)) {
+                                       if (!memcmp(filename, str_key->val, str_key->len) && ((uint)filename_len == str_key->len
+                                               || filename[str_key->len] == '/' || filename[str_key->len] == '\0')) {
+                                               if (NULL == (pphar = zend_hash_get_current_data_ptr(&cached_phars))) {
                                                        break;
                                                }
-                                               *ext_str = filename + (keylen - (*pphar)->ext_len);
+                                               *ext_str = filename + (str_key->len - pphar->ext_len);
                                                goto woohoo;
                                        }
                                }
@@ -2253,7 +2252,7 @@ int phar_split_fname(const char *filename, int filename_len, char **arch, int *a
 #ifdef PHP_WIN32
                                *arch = save;
 #else
-                               *arch = filename;
+                               *arch = (char*)filename;
 #endif
                        }
 
@@ -2297,7 +2296,7 @@ int phar_split_fname(const char *filename, int filename_len, char **arch, int *a
 int phar_open_executed_filename(char *alias, int alias_len, char **error TSRMLS_DC) /* {{{ */
 {
        char *fname;
-       zval *halt_constant;
+//???  zval *halt_constant;
        php_stream *fp;
        int fname_len;
        char *actual = NULL;
@@ -2321,17 +2320,13 @@ int phar_open_executed_filename(char *alias, int alias_len, char **error TSRMLS_
                return FAILURE;
        }
 
-       MAKE_STD_ZVAL(halt_constant);
-
-       if (0 == zend_get_constant("__COMPILER_HALT_OFFSET__", 24, halt_constant TSRMLS_CC)) {
-               FREE_ZVAL(halt_constant);
+       if (0 == zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1 TSRMLS_CC)) {
                if (error) {
                        spprintf(error, 0, "__HALT_COMPILER(); must be declared in a phar");
                }
                return FAILURE;
        }
 
-       FREE_ZVAL(halt_constant);
 
 #if PHP_API_VERSION < 20100412
        if (PG(safe_mode) && (!php_checkuid(fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
@@ -2469,9 +2464,9 @@ static inline void phar_set_32(char *buffer, int var) /* {{{ */
 #endif
 } /* }}} */
 
-static int phar_flush_clean_deleted_apply(void *data TSRMLS_DC) /* {{{ */
+static int phar_flush_clean_deleted_apply(zval *zv TSRMLS_DC) /* {{{ */
 {
-       phar_entry_info *entry = (phar_entry_info *)data;
+       phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv);
 
        if (entry->fp_refcount <= 0 && entry->is_deleted) {
                return ZEND_HASH_APPLY_REMOVE;
@@ -2607,7 +2602,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
                zend_string *suser_stub;
                if (len < 0) {
                        /* resource passed in */
-                       if (!(php_stream_from_zval_no_verify(stubfile, (zval **)user_stub))) {
+                       if (!(php_stream_from_zval_no_verify(stubfile, (zval *)user_stub))) {
                                if (closeoldfile) {
                                        php_stream_close(oldfile);
                                }
@@ -2717,20 +2712,18 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
        zend_hash_apply(&phar->manifest, phar_flush_clean_deleted_apply TSRMLS_CC);
 
        /* compress as necessary, calculate crcs, serialize meta-data, manifest size, and file sizes */
-       main_metadata_str.c = 0;
-       if (phar->metadata) {
+       main_metadata_str.s = NULL;
+       if (Z_TYPE(phar->metadata) != IS_UNDEF) {
                PHP_VAR_SERIALIZE_INIT(metadata_hash);
                php_var_serialize(&main_metadata_str, &phar->metadata, &metadata_hash TSRMLS_CC);
                PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
-       } else {
-               main_metadata_str.len = 0;
        }
        new_manifest_count = 0;
        offset = 0;
        for (zend_hash_internal_pointer_reset(&phar->manifest);
                zend_hash_has_more_elements(&phar->manifest) == SUCCESS;
                zend_hash_move_forward(&phar->manifest)) {
-               if (zend_hash_get_current_data(&phar->manifest, (void **)&entry) == FAILURE) {
+               if ((entry = zend_hash_get_current_data_ptr(&phar->manifest)) == NULL) {
                        continue;
                }
                if (entry->cfp) {
@@ -2762,25 +2755,23 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
                        /* we use this to calculate API version, 1.1.1 is used for phars with directories */
                        has_dirs = 1;
                }
-               if (entry->metadata) {
-                       if (entry->metadata_str.c) {
+               if (Z_TYPE(entry->metadata) != IS_UNDEF) {
+                       if (entry->metadata_str.s) {
                                smart_str_free(&entry->metadata_str);
                        }
-                       entry->metadata_str.c = 0;
-                       entry->metadata_str.len = 0;
+                       entry->metadata_str.s = NULL;
                        PHP_VAR_SERIALIZE_INIT(metadata_hash);
                        php_var_serialize(&entry->metadata_str, &entry->metadata, &metadata_hash TSRMLS_CC);
                        PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
                } else {
-                       if (entry->metadata_str.c) {
+                       if (entry->metadata_str.s) {
                                smart_str_free(&entry->metadata_str);
                        }
-                       entry->metadata_str.c = 0;
-                       entry->metadata_str.len = 0;
+                       entry->metadata_str.s = NULL;
                }
 
                /* 32 bits for filename length, length of filename, manifest + metadata, and add 1 for trailing / if a directory */
-               offset += 4 + entry->filename_len + sizeof(entry_buffer) + entry->metadata_str.len + (entry->is_dir ? 1 : 0);
+               offset += 4 + entry->filename_len + sizeof(entry_buffer) + (entry->metadata_str.s ? entry->metadata_str.s->len : 0) + (entry->is_dir ? 1 : 0);
 
                /* compress and rehash as necessary */
                if ((oldfile && !entry->is_modified) || entry->is_dir) {
@@ -2906,7 +2897,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
                phar->alias_len = 0;
        }
 
-       manifest_len = offset + phar->alias_len + sizeof(manifest) + main_metadata_str.len;
+       manifest_len = offset + phar->alias_len + sizeof(manifest) + (main_metadata_str.s ? main_metadata_str.s->len : 0);
        phar_set_32(manifest, manifest_len);
        /* Hack - see bug #65028, add padding byte to the end of the manifest */
        if(manifest[0] == '\r' || manifest[0] == '\n') {
@@ -2945,9 +2936,9 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
 
        phar->alias_len = restore_alias_len;
 
-       phar_set_32(manifest, main_metadata_str.len);
-       if (4 != php_stream_write(newfile, manifest, 4) || (main_metadata_str.len
-       && main_metadata_str.len != php_stream_write(newfile, main_metadata_str.c, main_metadata_str.len))) {
+       phar_set_32(manifest, main_metadata_str.s ? main_metadata_str.s->len : 0);
+       if (4 != php_stream_write(newfile, manifest, 4) || ((main_metadata_str.s ? main_metadata_str.s->len : 0)
+       && main_metadata_str.s->len != php_stream_write(newfile, main_metadata_str.s->val, main_metadata_str.s->len))) {
                smart_str_free(&main_metadata_str);
 
                if (closeoldfile) {
@@ -2973,7 +2964,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
                zend_hash_has_more_elements(&phar->manifest) == SUCCESS;
                zend_hash_move_forward(&phar->manifest)) {
 
-               if (zend_hash_get_current_data(&phar->manifest, (void **)&entry) == FAILURE) {
+               if ((entry = zend_hash_get_current_data_ptr(&phar->manifest)) == NULL) {
                        continue;
                }
 
@@ -3021,10 +3012,10 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
                phar_set_32(entry_buffer+8, entry->compressed_filesize);
                phar_set_32(entry_buffer+12, entry->crc32);
                phar_set_32(entry_buffer+16, entry->flags);
-               phar_set_32(entry_buffer+20, entry->metadata_str.len);
+               phar_set_32(entry_buffer+20, entry->metadata_str.s ? entry->metadata_str.s->len : 0);
 
                if (sizeof(entry_buffer) != php_stream_write(newfile, entry_buffer, sizeof(entry_buffer))
-               || entry->metadata_str.len != php_stream_write(newfile, entry->metadata_str.c, entry->metadata_str.len)) {
+               || entry->metadata_str.s->len != php_stream_write(newfile, entry->metadata_str.s->val, entry->metadata_str.s->len)) {
                        if (closeoldfile) {
                                php_stream_close(oldfile);
                        }
@@ -3061,7 +3052,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert,
                zend_hash_has_more_elements(&phar->manifest) == SUCCESS;
                zend_hash_move_forward(&phar->manifest)) {
 
-               if (zend_hash_get_current_data(&phar->manifest, (void **)&entry) == FAILURE) {
+               if ((entry = zend_hash_get_current_data_ptr(&phar->manifest)) == NULL) {
                        continue;
                }
 
@@ -3380,6 +3371,11 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
 typedef zend_op_array* (zend_compile_t)(zend_file_handle*, int TSRMLS_DC);
 typedef zend_compile_t* (compile_hook)(zend_compile_t *ptr);
 
+static void mime_type_dtor(zval *zv)
+{
+       free(Z_PTR_P(zv));
+}
+
 PHP_GINIT_FUNCTION(phar) /* {{{ */
 {
        phar_mime_type mime;
@@ -3387,13 +3383,13 @@ PHP_GINIT_FUNCTION(phar) /* {{{ */
        memset(phar_globals, 0, sizeof(zend_phar_globals));
        phar_globals->readonly = 1;
 
-       zend_hash_init(&phar_globals->mime_types, 0, NULL, NULL, 1);
+       zend_hash_init(&phar_globals->mime_types, 0, NULL, mime_type_dtor, 1);
 
 #define PHAR_SET_MIME(mimetype, ret, fileext) \
                mime.mime = mimetype; \
                mime.len = sizeof((mimetype))+1; \
                mime.type = ret; \
-               zend_hash_add(&phar_globals->mime_types, fileext, sizeof(fileext)-1, (void *)&mime, sizeof(phar_mime_type), NULL); \
+               zend_hash_str_add_mem(&phar_globals->mime_types, fileext, sizeof(fileext)-1, (void *)&mime, sizeof(phar_mime_type)); \
 
        PHAR_SET_MIME("text/html", PHAR_MIME_PHPS, "phps")
        PHAR_SET_MIME("text/plain", PHAR_MIME_OTHER, "c")
@@ -3490,8 +3486,8 @@ void phar_request_initialize(TSRMLS_D) /* {{{ */
        {
                PHAR_G(last_phar) = NULL;
                PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
-               PHAR_G(has_bz2) = zend_hash_exists(&module_registry, "bz2", sizeof("bz2"));
-               PHAR_G(has_zlib) = zend_hash_exists(&module_registry, "zlib", sizeof("zlib"));
+               PHAR_G(has_bz2) = zend_hash_str_exists(&module_registry, "bz2", sizeof("bz2")-1);
+               PHAR_G(has_zlib) = zend_hash_str_exists(&module_registry, "zlib", sizeof("zlib")-1);
                PHAR_GLOBALS->request_init = 1;
                PHAR_GLOBALS->request_ends = 0;
                PHAR_GLOBALS->request_done = 0;
@@ -3500,13 +3496,13 @@ void phar_request_initialize(TSRMLS_D) /* {{{ */
                zend_hash_init(&(PHAR_GLOBALS->phar_alias_map), 5, zend_get_hash_value, NULL, 0);
 
                if (PHAR_G(manifest_cached)) {
-                       phar_archive_data **pphar;
+                       phar_archive_data *pphar;
                        phar_entry_fp *stuff = (phar_entry_fp *) ecalloc(zend_hash_num_elements(&cached_phars), sizeof(phar_entry_fp));
 
                        for (zend_hash_internal_pointer_reset(&cached_phars);
-                       zend_hash_get_current_data(&cached_phars, (void **)&pphar) == SUCCESS;
+                       (pphar = zend_hash_get_current_data_ptr(&cached_phars)) != NULL;
                        zend_hash_move_forward(&cached_phars)) {
-                               stuff[pphar[0]->phar_pos].manifest = (phar_entry_fp_info *) ecalloc( zend_hash_num_elements(&(pphar[0]->manifest)), sizeof(phar_entry_fp_info));
+                               stuff[pphar->phar_pos].manifest = (phar_entry_fp_info *) ecalloc( zend_hash_num_elements(&(pphar->manifest)), sizeof(phar_entry_fp_info));
                        }
 
                        PHAR_GLOBALS->cached_fp = stuff;
@@ -3593,7 +3589,7 @@ PHP_MINFO_FUNCTION(phar) /* {{{ */
 #ifdef PHAR_HAVE_OPENSSL
        php_info_print_table_row(2, "Native OpenSSL support", "enabled");
 #else
-       if (zend_hash_exists(&module_registry, "openssl", sizeof("openssl"))) {
+       if (zend_hash_str_exists(&module_registry, "openssl", sizeof("openssl")-1)) {
                php_info_print_table_row(2, "OpenSSL support", "enabled");
        } else {
                php_info_print_table_row(2, "OpenSSL support", "disabled (install ext/openssl)");
index 12f005776372286d8e3450d26cc5ea640926fedf..c3610f8823495f2f35ea6a62f4a47acc16153616 100644 (file)
@@ -243,7 +243,7 @@ typedef struct _phar_entry_info {
        /* remainder */
        /* when changing compression, save old flags in case fp is NULL */
        php_uint32               old_flags;
-       zval                     *metadata;
+       zval                     metadata;
        int                      metadata_len; /* only used for cached manifests */
        php_uint32               filename_len;
        char                     *filename;
@@ -311,7 +311,7 @@ struct _phar_archive_data {
        php_uint32               sig_flags;
        int                      sig_len;
        char                     *signature;
-       zval                     *metadata;
+       zval                     metadata;
        int                      metadata_len; /* only used for cached manifests */
        uint                     phar_pos;
        /* if 1, then this alias was manually specified by the user and is not a permanent alias */
@@ -538,7 +538,7 @@ static inline void phar_set_inode(phar_entry_info *entry TSRMLS_DC) /* {{{ */
        tmp_len = entry->filename_len + entry->phar->fname_len;
        memcpy(tmp, entry->phar->fname, entry->phar->fname_len);
        memcpy(tmp + entry->phar->fname_len, entry->filename, entry->filename_len);
-       entry->inode = (unsigned short)zend_get_hash_value(tmp, tmp_len);
+       entry->inode = (unsigned short)zend_hash_func(tmp, tmp_len);
 }
 /* }}} */
 
@@ -570,8 +570,8 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len,
 char *phar_find_in_include_path(char *file, int file_len, phar_archive_data **pphar TSRMLS_DC);
 char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC);
 phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC);
-int phar_parse_metadata(char **buffer, zval **metadata, int zip_metadata_len TSRMLS_DC);
-void destroy_phar_manifest_entry(void *pDest);
+int phar_parse_metadata(char **buffer, zval *metadata, int zip_metadata_len TSRMLS_DC);
+void destroy_phar_manifest_entry(zval *zv);
 int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t position, int follow_links TSRMLS_DC);
 php_stream *phar_get_efp(phar_entry_info *entry, int follow_links TSRMLS_DC);
 int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error TSRMLS_DC);
index bb2b4a1098239c843932053f849b14d744edfa76..5a45dcfdbdd5ff04d7a7b90087f9cd038c171b3e 100644 (file)
@@ -47,7 +47,7 @@ static int phar_file_type(HashTable *mimes, char *file, char **mime_type TSRMLS_
                return PHAR_MIME_OTHER;
        }
        ++ext;
-       if (SUCCESS != zend_hash_find(mimes, ext, strlen(ext), (void **) &mime)) {
+       if (NULL == (mime = zend_hash_str_find_ptr(mimes, ext, strlen(ext)))) {
                *mime_type = "application/octet-stream";
                return PHAR_MIME_OTHER;
        }
@@ -59,43 +59,42 @@ static int phar_file_type(HashTable *mimes, char *file, char **mime_type TSRMLS_
 static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char *basename, int request_uri_len TSRMLS_DC) /* {{{ */
 {
        HashTable *_SERVER;
-       zval **stuff;
+       zval *stuff;
        char *path_info;
        int basename_len = strlen(basename);
        int code;
-       zval *temp;
+       zval temp;
 
        /* "tweak" $_SERVER variables requested in earlier call to Phar::mungServer() */
-       if (!PG(http_globals)[TRACK_VARS_SERVER]) {
+       if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_UNDEF) {
                return;
        }
 
-       _SERVER = Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]);
+       _SERVER = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]);
 
        /* PATH_INFO and PATH_TRANSLATED should always be munged */
-       if (SUCCESS == zend_hash_find(_SERVER, "PATH_INFO", sizeof("PATH_INFO"), (void **) &stuff)) {
-               path_info = Z_STRVAL_PP(stuff);
-               code = Z_STRLEN_PP(stuff);
-
-               if (Z_STRLEN_PP(stuff) > entry_len && !memcmp(Z_STRVAL_PP(stuff), entry, entry_len)) {
-                       ZVAL_STRINGL(*stuff, Z_STRVAL_PP(stuff) + entry_len, request_uri_len, 1);
-
-                       MAKE_STD_ZVAL(temp);
-                       ZVAL_STRINGL(temp, path_info, code, 0);
-
-                       zend_hash_update(_SERVER, "PHAR_PATH_INFO", sizeof("PHAR_PATH_INFO"), &temp, sizeof(zval **), NULL);
+       if (NULL != (stuff = zend_hash_str_find(_SERVER, "PATH_INFO", sizeof("PATH_INFO")-1))) {
+               path_info = Z_STRVAL_P(stuff);
+               code = Z_STRLEN_P(stuff);
+               if (code > entry_len && !memcmp(path_info, entry, entry_len)) {
+                       ZVAL_STR(&temp, Z_STR_P(stuff));
+                       ZVAL_STRINGL(stuff, path_info + entry_len, request_uri_len);
+                       zend_hash_str_update(_SERVER, "PHAR_PATH_INFO", sizeof("PHAR_PATH_INFO")-1, &temp);
                }
        }
 
-       if (SUCCESS == zend_hash_find(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), (void **) &stuff)) {
-               path_info = Z_STRVAL_PP(stuff);
-               code = Z_STRLEN_PP(stuff);
-               Z_STRLEN_PP(stuff) = spprintf(&(Z_STRVAL_PP(stuff)), 4096, "phar://%s%s", fname, entry);
+       if (NULL != (stuff = zend_hash_str_find(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED")-1))) {
+               char *str = NULL;
+               int len;
 
-               MAKE_STD_ZVAL(temp);
-               ZVAL_STRINGL(temp, path_info, code, 0);
+               // TODO: avoid reallocation ???
+               len = spprintf(&str, 4096, "phar://%s%s", fname, entry);
 
-               zend_hash_update(_SERVER, "PHAR_PATH_TRANSLATED", sizeof("PHAR_PATH_TRANSLATED"), (void *) &temp, sizeof(zval **), NULL);
+               ZVAL_STR(&temp, Z_STR_P(stuff));
+               ZVAL_STRINGL(stuff, str, len);
+               efree(str);
+
+               zend_hash_str_update(_SERVER, "PHAR_PATH_TRANSLATED", sizeof("PHAR_PATH_TRANSLATED")-1, (void *) &temp);
        }
 
        if (!PHAR_GLOBALS->phar_SERVER_mung_list) {
@@ -103,60 +102,51 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char
        }
 
        if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_REQUEST_URI) {
-               if (SUCCESS == zend_hash_find(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &stuff)) {
-                       path_info = Z_STRVAL_PP(stuff);
-                       code = Z_STRLEN_PP(stuff);
-
-                       if (Z_STRLEN_PP(stuff) > basename_len && !memcmp(Z_STRVAL_PP(stuff), basename, basename_len)) {
-                               ZVAL_STRINGL(*stuff, Z_STRVAL_PP(stuff) + basename_len, Z_STRLEN_PP(stuff) - basename_len, 1);
-
-                               MAKE_STD_ZVAL(temp);
-                               ZVAL_STRINGL(temp, path_info, code, 0);
-
-                               zend_hash_update(_SERVER, "PHAR_REQUEST_URI", sizeof("PHAR_REQUEST_URI"), (void *) &temp, sizeof(zval **), NULL);
+               if (NULL != (stuff = zend_hash_str_find(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI")-1))) {
+                       path_info = Z_STRVAL_P(stuff);
+                       code = Z_STRLEN_P(stuff);
+                       if (code > basename_len && !memcmp(path_info, basename, basename_len)) {
+                               ZVAL_STR(&temp, Z_STR_P(stuff));
+                               ZVAL_STRINGL(stuff, path_info + basename_len, code - basename_len);
+                               zend_hash_str_update(_SERVER, "PHAR_REQUEST_URI", sizeof("PHAR_REQUEST_URI")-1, &temp);
                        }
                }
        }
 
        if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_PHP_SELF) {
-               if (SUCCESS == zend_hash_find(_SERVER, "PHP_SELF", sizeof("PHP_SELF"), (void **) &stuff)) {
-                       path_info = Z_STRVAL_PP(stuff);
-                       code = Z_STRLEN_PP(stuff);
-
-                       if (Z_STRLEN_PP(stuff) > basename_len && !memcmp(Z_STRVAL_PP(stuff), basename, basename_len)) {
-                               ZVAL_STRINGL(*stuff, Z_STRVAL_PP(stuff) + basename_len, Z_STRLEN_PP(stuff) - basename_len, 1);
-
-                               MAKE_STD_ZVAL(temp);
-                               ZVAL_STRINGL(temp, path_info, code, 0);
-
-                               zend_hash_update(_SERVER, "PHAR_PHP_SELF", sizeof("PHAR_PHP_SELF"), (void *) &temp, sizeof(zval **), NULL);
+               if (NULL != (stuff = zend_hash_str_find(_SERVER, "PHP_SELF", sizeof("PHP_SELF")-1))) {
+                       path_info = Z_STRVAL_P(stuff);
+                       code = Z_STRLEN_P(stuff);
+
+                       if (code > basename_len && !memcmp(path_info, basename, basename_len)) {
+                               ZVAL_STR(&temp, Z_STR_P(stuff));
+                               ZVAL_STRINGL(stuff, path_info + basename_len, code - basename_len);
+                               zend_hash_str_update(_SERVER, "PHAR_PHP_SELF", sizeof("PHAR_PHP_SELF")-1, &temp);
                        }
                }
        }
 
        if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_SCRIPT_NAME) {
-               if (SUCCESS == zend_hash_find(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &stuff)) {
-                       path_info = Z_STRVAL_PP(stuff);
-                       code = Z_STRLEN_PP(stuff);
-                       ZVAL_STRINGL(*stuff, entry, entry_len, 1);
-
-                       MAKE_STD_ZVAL(temp);
-                       ZVAL_STRINGL(temp, path_info, code, 0);
-
-                       zend_hash_update(_SERVER, "PHAR_SCRIPT_NAME", sizeof("PHAR_SCRIPT_NAME"), (void *) &temp, sizeof(zval **), NULL);
+               if (NULL != (stuff = zend_hash_str_find(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1))) {
+                       ZVAL_STR(&temp, Z_STR_P(stuff));
+                       ZVAL_STRINGL(stuff, entry, entry_len);
+                       zend_hash_str_update(_SERVER, "PHAR_SCRIPT_NAME", sizeof("PHAR_SCRIPT_NAME")-1, &temp);
                }
        }
 
        if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_SCRIPT_FILENAME) {
-               if (SUCCESS == zend_hash_find(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &stuff)) {
-                       path_info = Z_STRVAL_PP(stuff);
-                       code = Z_STRLEN_PP(stuff);
-                       Z_STRLEN_PP(stuff) = spprintf(&(Z_STRVAL_PP(stuff)), 4096, "phar://%s%s", fname, entry);
+               if (NULL != (stuff = zend_hash_str_find(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME")-1))) {
+                       char *str = NULL;
+                       int len;
+
+                       // TODO: avoid reallocation ???
+                       len = spprintf(&str, 4096, "phar://%s%s", fname, entry);
 
-                       MAKE_STD_ZVAL(temp);
-                       ZVAL_STRINGL(temp, path_info, code, 0);
+                       ZVAL_STR(&temp, Z_STR_P(stuff));
+                       ZVAL_STRINGL(stuff, str, len);
+                       efree(str);
 
-                       zend_hash_update(_SERVER, "PHAR_SCRIPT_FILENAME", sizeof("PHAR_SCRIPT_FILENAME"), (void *) &temp, sizeof(zval **), NULL);
+                       zend_hash_str_update(_SERVER, "PHAR_SCRIPT_FILENAME", sizeof("PHAR_SCRIPT_FILENAME")-1, &temp);
                }
        }
 }
@@ -169,10 +159,11 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
        zend_syntax_highlighter_ini syntax_highlighter_ini;
        sapi_header_line ctr = {0};
        size_t got;
-       int dummy = 1, name_len;
+       zval dummy;
+       int name_len;
        zend_file_handle file_handle;
        zend_op_array *new_op_array;
-       zval *result = NULL;
+       zval result;
        php_stream *fp;
        off_t position;
 
@@ -258,7 +249,8 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
                        PHAR_G(cwd) = NULL;
                        PHAR_G(cwd_len) = 0;
 
-                       if (zend_hash_add(&EG(included_files), name, name_len+1, (void *)&dummy, sizeof(int), NULL) == SUCCESS) {
+                       ZVAL_NULL(&dummy);
+                       if (zend_hash_str_add(&EG(included_files), name, name_len, &dummy) != NULL) {
                                if ((cwd = zend_memrchr(entry, '/', entry_len))) {
                                        PHAR_G(cwd_init) = 1;
                                        if (entry == cwd) {
@@ -277,7 +269,7 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
                                new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
 
                                if (!new_op_array) {
-                                       zend_hash_del(&EG(included_files), name, name_len+1);
+                                       zend_hash_str_del(&EG(included_files), name, name_len);
                                }
 
                                zend_destroy_file_handle(&file_handle TSRMLS_CC);
@@ -290,11 +282,11 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
                        efree(arch);
 #endif
                        if (new_op_array) {
-                               EG(return_value_ptr_ptr) = &result;
+                               ZVAL_UNDEF(&result);
                                EG(active_op_array) = new_op_array;
 
                                zend_try {
-                                       zend_execute(new_op_array TSRMLS_CC);
+                                       zend_execute(new_op_array, &result TSRMLS_CC);
                                        if (PHAR_G(cwd)) {
                                                efree(PHAR_G(cwd));
                                                PHAR_G(cwd) = NULL;
@@ -305,11 +297,7 @@ static int phar_file_action(phar_archive_data *phar, phar_entry_info *info, char
                                        efree(name);
                                        destroy_op_array(new_op_array TSRMLS_CC);
                                        efree(new_op_array);
-
-
-                                       if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) {
-                                               zval_ptr_dtor(EG(return_value_ptr_ptr));
-                                       }
+                                       zval_ptr_dtor(&result);
                                } zend_catch {
                                        if (PHAR_G(cwd)) {
                                                efree(PHAR_G(cwd));
@@ -377,17 +365,17 @@ static void phar_postprocess_ru_web(char *fname, int fname_len, char **entry, in
 {
        char *e = *entry + 1, *u = NULL, *u1 = NULL, *saveu = NULL;
        int e_len = *entry_len - 1, u_len = 0;
-       phar_archive_data **pphar = NULL;
+       phar_archive_data *pphar;
 
        /* we already know we can retrieve the phar if we reach here */
-       zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **) &pphar);
+       pphar = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len);
 
        if (!pphar && PHAR_G(manifest_cached)) {
-               zend_hash_find(&cached_phars, fname, fname_len, (void **) &pphar);
+               pphar = zend_hash_str_find_ptr(&cached_phars, fname, fname_len);
        }
 
        do {
-               if (zend_hash_exists(&((*pphar)->manifest), e, e_len)) {
+               if (zend_hash_str_exists(&(pphar->manifest), e, e_len)) {
                        if (u) {
                                u[0] = '/';
                                *ru = estrndup(u, u_len+1);
@@ -454,15 +442,18 @@ PHP_METHOD(Phar, running)
        if (fname_len > 7 && !memcmp(fname, "phar://", 7) && SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
                efree(entry);
                if (retphar) {
-                       RETVAL_STRINGL(fname, arch_len + 7, 1);
+                       RETVAL_STRINGL(fname, arch_len + 7);
                        efree(arch);
                        return;
                } else {
-                       RETURN_STRINGL(arch, arch_len, 0);
+                       // TODO: avoid reallocation ???
+                       RETVAL_STRINGL(arch, arch_len);
+                       efree(arch);
+                       return;
                }
        }
 
-       RETURN_STRINGL("", 0, 1);
+       RETURN_EMPTY_STRING();
 }
 /* }}} */
 
@@ -476,7 +467,7 @@ PHP_METHOD(Phar, mount)
 {
        char *fname, *arch = NULL, *entry = NULL, *path, *actual;
        int fname_len, arch_len, entry_len, path_len, actual_len;
-       phar_archive_data **pphar;
+       phar_archive_data *pphar;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &path, &path_len, &actual, &actual_len) == FAILURE) {
                return;
@@ -499,9 +490,9 @@ PHP_METHOD(Phar, mount)
                        return;
                }
 carry_on2:
-               if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) {
-                       if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, arch, arch_len, (void **)&pphar)) {
-                               if (SUCCESS == phar_copy_on_write(pphar TSRMLS_CC)) {
+               if (NULL == (pphar = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len))) {
+                       if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len))) {
+                               if (SUCCESS == phar_copy_on_write(&pphar TSRMLS_CC)) {
                                        goto carry_on;
                                }
                        }
@@ -514,7 +505,7 @@ carry_on2:
                        return;
                }
 carry_on:
-               if (SUCCESS != phar_mount_entry(*pphar, actual, actual_len, path, path_len TSRMLS_CC)) {
+               if (SUCCESS != phar_mount_entry(pphar, actual, actual_len, path, path_len TSRMLS_CC)) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Mounting of %s to %s within phar %s failed", path, actual, arch);
                        if (path && path == entry) {
                                efree(entry);
@@ -536,10 +527,10 @@ carry_on:
                }
 
                return;
-       } else if (PHAR_GLOBALS->phar_fname_map.arHash && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **)&pphar)) {
+       } else if (PHAR_GLOBALS->phar_fname_map.arHash && NULL != (pphar = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len))) {
                goto carry_on;
-       } else if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, fname, fname_len, (void **)&pphar)) {
-               if (SUCCESS == phar_copy_on_write(pphar TSRMLS_CC)) {
+       } else if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
+               if (SUCCESS == phar_copy_on_write(&pphar TSRMLS_CC)) {
                        goto carry_on;
                }
 
@@ -565,7 +556,7 @@ PHP_METHOD(Phar, webPhar)
 {
        zval *mimeoverride = NULL, *rewrite = NULL;
        char *alias = NULL, *error, *index_php = NULL, *f404 = NULL, *ru = NULL;
-       int alias_len = 0, ret, f404_len = 0, free_pathinfo = 0, ru_len = 0;
+       int alias_len = 0, f404_len = 0, free_pathinfo = 0, ru_len = 0;
        char *fname, *path_info, *mime_type = NULL, *entry, *pt;
        const char *basename;
        int fname_len, entry_len, code, index_php_len = 0, not_cgi;
@@ -608,31 +599,31 @@ PHP_METHOD(Phar, webPhar)
        if ((strlen(sapi_module.name) == sizeof("cgi-fcgi")-1 && !strncmp(sapi_module.name, "cgi-fcgi", sizeof("cgi-fcgi")-1))
                || (strlen(sapi_module.name) == sizeof("cgi")-1 && !strncmp(sapi_module.name, "cgi", sizeof("cgi")-1))) {
 
-               if (PG(http_globals)[TRACK_VARS_SERVER]) {
-                       HashTable *_server = Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]);
-                       zval **z_script_name, **z_path_info;
+               if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF) {
+                       HashTable *_server = Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]);
+                       zval *z_script_name, *z_path_info;
 
-                       if (SUCCESS != zend_hash_find(_server, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void**)&z_script_name) ||
-                               IS_STRING != Z_TYPE_PP(z_script_name) ||
-                               !strstr(Z_STRVAL_PP(z_script_name), basename)) {
+                       if (NULL == (z_script_name = zend_hash_str_find(_server, "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1)) ||
+                               IS_STRING != Z_TYPE_P(z_script_name) ||
+                               !strstr(Z_STRVAL_P(z_script_name), basename)) {
                                return;
                        }
 
-                       if (SUCCESS == zend_hash_find(_server, "PATH_INFO", sizeof("PATH_INFO"), (void**)&z_path_info) &&
-                               IS_STRING == Z_TYPE_PP(z_path_info)) {
-                               entry_len = Z_STRLEN_PP(z_path_info);
-                               entry = estrndup(Z_STRVAL_PP(z_path_info), entry_len);
-                               path_info = emalloc(Z_STRLEN_PP(z_script_name) + entry_len + 1);
-                               memcpy(path_info, Z_STRVAL_PP(z_script_name), Z_STRLEN_PP(z_script_name));
-                               memcpy(path_info + Z_STRLEN_PP(z_script_name), entry, entry_len + 1);
+                       if (NULL != (z_path_info = zend_hash_str_find(_server, "PATH_INFO", sizeof("PATH_INFO")-1)) &&
+                               IS_STRING == Z_TYPE_P(z_path_info)) {
+                               entry_len = Z_STRLEN_P(z_path_info);
+                               entry = estrndup(Z_STRVAL_P(z_path_info), entry_len);
+                               path_info = emalloc(Z_STRLEN_P(z_script_name) + entry_len + 1);
+                               memcpy(path_info, Z_STRVAL_P(z_script_name), Z_STRLEN_P(z_script_name));
+                               memcpy(path_info + Z_STRLEN_P(z_script_name), entry, entry_len + 1);
                                free_pathinfo = 1;
                        } else {
                                entry_len = 0;
                                entry = estrndup("", 0);
-                               path_info = Z_STRVAL_PP(z_script_name);
+                               path_info = Z_STRVAL_P(z_script_name);
                        }
 
-                       pt = estrndup(Z_STRVAL_PP(z_script_name), Z_STRLEN_PP(z_script_name));
+                       pt = estrndup(Z_STRVAL_P(z_script_name), Z_STRLEN_P(z_script_name));
 
                } else {
                        char *testit;
@@ -679,11 +670,9 @@ PHP_METHOD(Phar, webPhar)
        if (rewrite) {
                zend_fcall_info fci;
                zend_fcall_info_cache fcc;
-               zval *params, *retval_ptr, **zp[1];
+               zval params, retval;
 
-               MAKE_STD_ZVAL(params);
-               ZVAL_STRINGL(params, entry, entry_len, 1);
-               zp[0] = &params;
+               ZVAL_STRINGL(&params, entry, entry_len);
 
                if (FAILURE == zend_fcall_info_init(rewrite, 0, &fci, &fcc, NULL, NULL TSRMLS_CC)) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar error: invalid rewrite callback");
@@ -696,9 +685,9 @@ PHP_METHOD(Phar, webPhar)
                }
 
                fci.param_count = 1;
-               fci.params = zp;
-               Z_ADDREF_P(params);
-               fci.retval_ptr_ptr = &retval_ptr;
+               fci.params = &params;
+               Z_ADDREF(params);
+               fci.retval = &retval;
 
                if (FAILURE == zend_call_function(&fci, &fcc TSRMLS_CC)) {
                        if (!EG(exception)) {
@@ -712,7 +701,7 @@ PHP_METHOD(Phar, webPhar)
                        return;
                }
 
-               if (!fci.retval_ptr_ptr || !retval_ptr) {
+               if (Z_TYPE_P(fci.retval) == IS_UNDEF || Z_TYPE(retval) == IS_UNDEF) {
                        if (free_pathinfo) {
                                efree(path_info);
                        }
@@ -720,20 +709,21 @@ PHP_METHOD(Phar, webPhar)
                        return;
                }
 
-               switch (Z_TYPE_P(retval_ptr)) {
+               switch (Z_TYPE(retval)) {
                        case IS_STRING:
                                efree(entry);
 
-                               if (fci.retval_ptr_ptr != &retval_ptr) {
-                                       entry = estrndup(Z_STRVAL_PP(fci.retval_ptr_ptr), Z_STRLEN_PP(fci.retval_ptr_ptr));
-                                       entry_len = Z_STRLEN_PP(fci.retval_ptr_ptr);
+                               if (fci.retval != &retval) {
+                                       entry = estrndup(Z_STRVAL_P(fci.retval), Z_STRLEN_P(fci.retval));
+                                       entry_len = Z_STRLEN_P(fci.retval);
                                } else {
-                                       entry = Z_STRVAL_P(retval_ptr);
-                                       entry_len = Z_STRLEN_P(retval_ptr);
+                                       entry = Z_STRVAL(retval);
+                                       entry_len = Z_STRLEN(retval);
                                }
 
                                break;
-                       case IS_BOOL:
+                       case IS_TRUE:
+                       case IS_FALSE:
                                phar_do_403(entry, entry_len TSRMLS_CC);
 
                                if (free_pathinfo) {
@@ -743,8 +733,6 @@ PHP_METHOD(Phar, webPhar)
                                zend_bailout();
                                return;
                        default:
-                               efree(retval_ptr);
-
                                if (free_pathinfo) {
                                        efree(path_info);
                                }
@@ -831,17 +819,17 @@ PHP_METHOD(Phar, webPhar)
 
        if (mimeoverride && zend_hash_num_elements(Z_ARRVAL_P(mimeoverride))) {
                const char *ext = zend_memrchr(entry, '.', entry_len);
-               zval **val;
+               zval *val;
 
                if (ext) {
                        ++ext;
 
-                       if (SUCCESS == zend_hash_find(Z_ARRVAL_P(mimeoverride), ext, strlen(ext)+1, (void **) &val)) {
-                               switch (Z_TYPE_PP(val)) {
+                       if (NULL != (val = zend_hash_str_find(Z_ARRVAL_P(mimeoverride), ext, strlen(ext)))) {
+                               switch (Z_TYPE_P(val)) {
                                        case IS_LONG:
-                                               if (Z_LVAL_PP(val) == PHAR_MIME_PHP || Z_LVAL_PP(val) == PHAR_MIME_PHPS) {
+                                               if (Z_LVAL_P(val) == PHAR_MIME_PHP || Z_LVAL_P(val) == PHAR_MIME_PHPS) {
                                                        mime_type = "";
-                                                       code = Z_LVAL_PP(val);
+                                                       code = Z_LVAL_P(val);
                                                } else {
                                                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Unknown mime type specifier used, only Phar::PHP, Phar::PHPS and a mime type string are allowed");
 #ifdef PHP_WIN32
@@ -851,7 +839,7 @@ PHP_METHOD(Phar, webPhar)
                                                }
                                                break;
                                        case IS_STRING:
-                                               mime_type = Z_STRVAL_PP(val);
+                                               mime_type = Z_STRVAL_P(val);
                                                code = PHAR_MIME_OTHER;
                                                break;
                                        default:
@@ -868,7 +856,7 @@ PHP_METHOD(Phar, webPhar)
        if (!mime_type) {
                code = phar_file_type(&PHAR_G(mime_types), entry, &mime_type TSRMLS_CC);
        }
-       ret = phar_file_action(phar, info, mime_type, code, entry, entry_len, fname, pt, ru, ru_len TSRMLS_CC);
+       phar_file_action(phar, info, mime_type, code, entry, entry_len, fname, pt, ru, ru_len TSRMLS_CC);
 }
 /* }}} */
 
@@ -899,32 +887,32 @@ PHP_METHOD(Phar, mungServer)
        phar_request_initialize(TSRMLS_C);
 
        for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(mungvalues)); SUCCESS == zend_hash_has_more_elements(Z_ARRVAL_P(mungvalues)); zend_hash_move_forward(Z_ARRVAL_P(mungvalues))) {
-               zval **data = NULL;
+               zval *data = NULL;
 
-               if (SUCCESS != zend_hash_get_current_data(Z_ARRVAL_P(mungvalues), (void **) &data)) {
+               if (NULL == (data = zend_hash_get_current_data(Z_ARRVAL_P(mungvalues)))) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "unable to retrieve array value in Phar::mungServer()");
                        return;
                }
 
-               if (Z_TYPE_PP(data) != IS_STRING) {
+               if (Z_TYPE_P(data) != IS_STRING) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME");
                        return;
                }
 
-               if (Z_STRLEN_PP(data) == sizeof("PHP_SELF")-1 && !strncmp(Z_STRVAL_PP(data), "PHP_SELF", sizeof("PHP_SELF")-1)) {
+               if (Z_STRLEN_P(data) == sizeof("PHP_SELF")-1 && !strncmp(Z_STRVAL_P(data), "PHP_SELF", sizeof("PHP_SELF")-1)) {
                        PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_PHP_SELF;
                }
 
-               if (Z_STRLEN_PP(data) == sizeof("REQUEST_URI")-1) {
-                       if (!strncmp(Z_STRVAL_PP(data), "REQUEST_URI", sizeof("REQUEST_URI")-1)) {
+               if (Z_STRLEN_P(data) == sizeof("REQUEST_URI")-1) {
+                       if (!strncmp(Z_STRVAL_P(data), "REQUEST_URI", sizeof("REQUEST_URI")-1)) {
                                PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_REQUEST_URI;
                        }
-                       if (!strncmp(Z_STRVAL_PP(data), "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1)) {
+                       if (!strncmp(Z_STRVAL_P(data), "SCRIPT_NAME", sizeof("SCRIPT_NAME")-1)) {
                                PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_SCRIPT_NAME;
                        }
                }
 
-               if (Z_STRLEN_PP(data) == sizeof("SCRIPT_FILENAME")-1 && !strncmp(Z_STRVAL_PP(data), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME")-1)) {
+               if (Z_STRLEN_P(data) == sizeof("SCRIPT_FILENAME")-1 && !strncmp(Z_STRVAL_P(data), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME")-1)) {
                        PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_SCRIPT_FILENAME;
                }
        }
@@ -970,7 +958,9 @@ PHP_METHOD(Phar, createDefaultStub)
                efree(error);
                return;
        }
-       RETURN_STRINGL(stub, stub_len, 0);
+       // TODO: avoid reallocation ???
+       RETVAL_STRINGL(stub, stub_len);
+       efree(stub);
 }
 /* }}} */
 
@@ -1024,7 +1014,7 @@ PHP_METHOD(Phar, apiVersion)
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
-       RETURN_STRINGL(PHP_PHAR_API_VERSION, sizeof(PHP_PHAR_API_VERSION)-1, 1);
+       RETURN_STRINGL(PHP_PHAR_API_VERSION, sizeof(PHP_PHAR_API_VERSION)-1);
 }
 /* }}}*/
 
@@ -1148,7 +1138,7 @@ PHP_METHOD(Phar, __construct)
        phar_archive_data   *phar_data;
        zval *zobj = getThis(), arg1, arg2;
 
-       phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       phar_obj = (phar_archive_object*)Z_OBJ_P(getThis());
 
        is_data = instanceof_function(Z_OBJCE_P(zobj), phar_ce_data TSRMLS_CC);
 
@@ -1246,19 +1236,19 @@ PHP_METHOD(Phar, __construct)
                fname_len = spprintf(&fname, 0, "phar://%s", phar_data->fname);
        }
 
-       INIT_PZVAL(&arg1);
-       ZVAL_STRINGL(&arg1, fname, fname_len, 0);
-       INIT_PZVAL(&arg2);
+       ZVAL_STRINGL(&arg1, fname, fname_len);
        ZVAL_LONG(&arg2, flags);
 
-       zend_call_method_with_2_params(&zobj, Z_OBJCE_P(zobj), 
+       zend_call_method_with_2_params(zobj, Z_OBJCE_P(zobj), 
                &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg1, &arg2);
 
+       zval_ptr_dtor(&arg1);
+
        if (!phar_data->is_persistent) {
                phar_obj->arc.archive->is_data = is_data;
        } else if (!EG(exception)) {
                /* register this guy so we can modify if necessary */
-               zend_hash_add(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive), (void *) &phar_obj, sizeof(phar_archive_object **), NULL);
+               zend_hash_str_add_ptr(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive), phar_obj);
        }
 
        phar_obj->spl.info_class = phar_ce_entry;
@@ -1287,7 +1277,7 @@ PHP_METHOD(Phar, getSupportedSignatures)
 #if PHAR_HAVE_OPENSSL
        add_next_index_stringl(return_value, "OpenSSL", 7);
 #else
-       if (zend_hash_exists(&module_registry, "openssl", sizeof("openssl"))) {
+       if (zend_hash_str_exists(&module_registry, "openssl", sizeof("openssl")-1)) {
                add_next_index_stringl(return_value, "OpenSSL", 7);
        }
 #endif
@@ -1384,7 +1374,7 @@ PHP_METHOD(Phar, unlinkArchive)
 #if HAVE_SPL
 
 #define PHAR_ARCHIVE_OBJECT() \
-       phar_archive_object *phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
+       phar_archive_object *phar_obj = (phar_archive_object*)Z_OBJ_P((getThis())); \
        if (!phar_obj->arc.archive) { \
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
                        "Cannot call method on an uninitialized Phar object"); \
@@ -1396,10 +1386,10 @@ PHP_METHOD(Phar, unlinkArchive)
  */
 PHP_METHOD(Phar, __destruct)
 {
-       phar_archive_object *phar_obj = (phar_archive_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       phar_archive_object *phar_obj = (phar_archive_object*)Z_OBJ_P((getThis()));
 
        if (phar_obj->arc.archive && phar_obj->arc.archive->is_persistent) {
-               zend_hash_del(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive));
+               zend_hash_str_del(&PHAR_GLOBALS->phar_persist_map, (const char *) phar_obj->arc.archive, sizeof(phar_obj->arc.archive));
        }
 }
 /* }}} */
@@ -1416,7 +1406,7 @@ struct _phar_t {
 
 static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */
 {
-       zval **value;
+       zval *value;
        zend_bool close_fp = 1;
        struct _phar_t *p_obj = (struct _phar_t*) puser;
        uint str_key_len, base_len = p_obj->l, fname_len;
@@ -1429,7 +1419,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
        phar_archive_object *phar_obj = p_obj->p;
        char *str = "[stream]";
 
-       iter->funcs->get_current_data(iter, &value TSRMLS_CC);
+       value = iter->funcs->get_current_data(iter TSRMLS_CC);
 
        if (EG(exception)) {
                return ZEND_HASH_APPLY_STOP;
@@ -1441,7 +1431,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
                return ZEND_HASH_APPLY_STOP;
        }
 
-       switch (Z_TYPE_PP(value)) {
+       switch (Z_TYPE_P(value)) {
                case IS_STRING:
                        break;
                case IS_RESOURCE:
@@ -1480,10 +1470,10 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
                        opened = (char *) estrndup(str, sizeof("[stream]") + 1);
                        goto after_open_fp;
                case IS_OBJECT:
-                       if (instanceof_function(Z_OBJCE_PP(value), spl_ce_SplFileInfo TSRMLS_CC)) {
+                       if (instanceof_function(Z_OBJCE_P(value), spl_ce_SplFileInfo TSRMLS_CC)) {
                                char *test = NULL;
                                zval dummy;
-                               spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(*value TSRMLS_CC);
+                               spl_filesystem_object *intern = (spl_filesystem_object*)Z_OBJ_P(value);
 
                                if (!base_len) {
                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Iterator %v returns an SplFileInfo object, so base directory must be specified", ce->name);
@@ -1496,7 +1486,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
                                                fname_len = spprintf(&fname, 0, "%s%c%s", test, DEFAULT_SLASH, intern->u.dir.entry.d_name);
                                                php_stat(fname, fname_len, FS_IS_DIR, &dummy TSRMLS_CC);
 
-                                               if (Z_BVAL(dummy)) {
+                                               if (Z_TYPE(dummy) == IS_TRUE) {
                                                        /* ignore directories */
                                                        efree(fname);
                                                        return ZEND_HASH_APPLY_KEEP;
@@ -1534,8 +1524,8 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
                        return ZEND_HASH_APPLY_STOP;
        }
 
-       fname = Z_STRVAL_PP(value);
-       fname_len = Z_STRLEN_PP(value);
+       fname = Z_STRVAL_P(value);
+       fname_len = Z_STRLEN_P(value);
 
 phar_spl_fileinfo:
        if (base_len) {
@@ -1746,7 +1736,7 @@ PHP_METHOD(Phar, buildFromDirectory)
        char *dir, *error, *regex = NULL;
        int dir_len, regex_len = 0;
        zend_bool apply_reg = 0;
-       zval arg, arg2, *iter, *iteriter, *regexiter = NULL;
+       zval arg, arg2, iter, iteriter, regexiter;
        struct _phar_t pass;
 
        PHAR_ARCHIVE_OBJECT();
@@ -1761,30 +1751,25 @@ PHP_METHOD(Phar, buildFromDirectory)
                RETURN_FALSE;
        }
 
-       MAKE_STD_ZVAL(iter);
-
-       if (SUCCESS != object_init_ex(iter, spl_ce_RecursiveDirectoryIterator)) {
+       if (SUCCESS != object_init_ex(&iter, spl_ce_RecursiveDirectoryIterator)) {
                zval_ptr_dtor(&iter);
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate directory iterator for %s", phar_obj->arc.archive->fname);
                RETURN_FALSE;
        }
 
-       INIT_PZVAL(&arg);
-       ZVAL_STRINGL(&arg, dir, dir_len, 0);
-       INIT_PZVAL(&arg2);
+       ZVAL_STRINGL(&arg, dir, dir_len);
        ZVAL_LONG(&arg2, SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS);
 
        zend_call_method_with_2_params(&iter, spl_ce_RecursiveDirectoryIterator, 
                        &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg, &arg2);
 
+       zval_ptr_dtor(&arg);
        if (EG(exception)) {
                zval_ptr_dtor(&iter);
                RETURN_FALSE;
        }
 
-       MAKE_STD_ZVAL(iteriter);
-
-       if (SUCCESS != object_init_ex(iteriter, spl_ce_RecursiveIteratorIterator)) {
+       if (SUCCESS != object_init_ex(&iteriter, spl_ce_RecursiveIteratorIterator)) {
                zval_ptr_dtor(&iter);
                zval_ptr_dtor(&iteriter);
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate directory iterator for %s", phar_obj->arc.archive->fname);
@@ -1792,7 +1777,7 @@ PHP_METHOD(Phar, buildFromDirectory)
        }
 
        zend_call_method_with_1_params(&iteriter, spl_ce_RecursiveIteratorIterator, 
-                       &spl_ce_RecursiveIteratorIterator->constructor, "__construct", NULL, iter);
+                       &spl_ce_RecursiveIteratorIterator->constructor, "__construct", NULL, &iter);
 
        if (EG(exception)) {
                zval_ptr_dtor(&iter);
@@ -1804,25 +1789,24 @@ PHP_METHOD(Phar, buildFromDirectory)
 
        if (regex_len > 0) {
                apply_reg = 1;
-               MAKE_STD_ZVAL(regexiter);
 
-               if (SUCCESS != object_init_ex(regexiter, spl_ce_RegexIterator)) {
+               if (SUCCESS != object_init_ex(&regexiter, spl_ce_RegexIterator)) {
                        zval_ptr_dtor(&iteriter);
-                       zval_dtor(regexiter);
+                       zval_dtor(&regexiter);
                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate regex iterator for %s", phar_obj->arc.archive->fname);
                        RETURN_FALSE;
                }
 
-               INIT_PZVAL(&arg2);
-               ZVAL_STRINGL(&arg2, regex, regex_len, 0);
+               ZVAL_STRINGL(&arg2, regex, regex_len);
 
                zend_call_method_with_2_params(&regexiter, spl_ce_RegexIterator, 
-                       &spl_ce_RegexIterator->constructor, "__construct", NULL, iteriter, &arg2);
+                       &spl_ce_RegexIterator->constructor, "__construct", NULL, &iteriter, &arg2);
+               zval_ptr_dtor(&arg2);
        }
 
        array_init(return_value);
 
-       pass.c = apply_reg ? Z_OBJCE_P(regexiter) : Z_OBJCE_P(iteriter);
+       pass.c = apply_reg ? Z_OBJCE(regexiter) : Z_OBJCE(iteriter);
        pass.p = phar_obj;
        pass.b = dir;
        pass.l = dir_len;
@@ -1844,7 +1828,7 @@ PHP_METHOD(Phar, buildFromDirectory)
                return;
        }
 
-       if (SUCCESS == spl_iterator_apply((apply_reg ? regexiter : iteriter), (spl_iterator_apply_func_t) phar_build, (void *) &pass TSRMLS_CC)) {
+       if (SUCCESS == spl_iterator_apply((apply_reg ? &regexiter : &iteriter), (spl_iterator_apply_func_t) phar_build, (void *) &pass TSRMLS_CC)) {
                zval_ptr_dtor(&iteriter);
 
                if (apply_reg) {
@@ -2020,19 +2004,19 @@ static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp TSRMLS
 }
 /* }}} */
 
-static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC) /* {{{ */
+static zend_object *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC) /* {{{ */
 {
        const char *oldname = NULL;
        char *oldpath = NULL;
        char *basename = NULL, *basepath = NULL;
        char *newname = NULL, *newpath = NULL;
-       zval *ret, arg1;
+       zval ret, arg1;
        zend_class_entry *ce;
        char *error;
        const char *pcr_error;
        int ext_len = ext ? strlen(ext) : 0;
        int oldname_len;
-       phar_archive_data **pphar = NULL;
+       phar_archive_data *pphar = NULL;
        php_stream_statbuf ssb;
 
        if (!ext) {
@@ -2113,23 +2097,23 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
        efree(basepath);
        efree(newname);
 
-       if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, newpath, phar->fname_len, (void **) &pphar)) {
+       if (PHAR_G(manifest_cached) && NULL != (pphar = zend_hash_str_find_ptr(&cached_phars, newpath, phar->fname_len))) {
                efree(oldpath);
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars, new phar name is in phar.cache_list", phar->fname);
                return NULL;
        }
 
-       if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void **) &pphar)) {
-               if ((*pphar)->fname_len == phar->fname_len && !memcmp((*pphar)->fname, phar->fname, phar->fname_len)) {
+       if (NULL != (pphar = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len))) {
+               if (pphar->fname_len == phar->fname_len && !memcmp(pphar->fname, phar->fname, phar->fname_len)) {
                        if (!zend_hash_num_elements(&phar->manifest)) {
-                               (*pphar)->is_tar = phar->is_tar;
-                               (*pphar)->is_zip = phar->is_zip;
-                               (*pphar)->is_data = phar->is_data;
-                               (*pphar)->flags = phar->flags;
-                               (*pphar)->fp = phar->fp;
+                               pphar->is_tar = phar->is_tar;
+                               pphar->is_zip = phar->is_zip;
+                               pphar->is_data = phar->is_data;
+                               pphar->flags = phar->flags;
+                               pphar->fp = phar->fp;
                                phar->fp = NULL;
                                phar_destroy_phar_data(phar TSRMLS_CC);
-                               phar = *pphar;
+                               phar = pphar;
                                phar->refcount++;
                                newpath = oldpath;
                                goto its_ok;
@@ -2161,7 +2145,7 @@ its_ok:
                                phar->alias = estrndup(newpath, strlen(newpath));
                                phar->alias_len = strlen(newpath);
                                phar->is_temporary_alias = 1;
-                               zend_hash_update(&(PHAR_GLOBALS->phar_alias_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL);
+                               zend_hash_str_update_ptr(&(PHAR_GLOBALS->phar_alias_map), newpath, phar->fname_len, phar);
                        }
                }
 
@@ -2177,7 +2161,7 @@ its_ok:
                phar->alias_len = 0;
        }
 
-       if ((!pphar || phar == *pphar) && SUCCESS != zend_hash_update(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, (void*)&phar, sizeof(phar_archive_data*), NULL)) {
+       if ((!pphar || phar == pphar) && NULL == zend_hash_str_update_ptr(&(PHAR_GLOBALS->phar_fname_map), newpath, phar->fname_len, phar)) {
                efree(oldpath);
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to add newly converted phar \"%s\" to the list of phars", phar->fname);
                return NULL;
@@ -2200,27 +2184,26 @@ its_ok:
                ce = phar_ce_archive;
        }
 
-       MAKE_STD_ZVAL(ret);
-
-       if (SUCCESS != object_init_ex(ret, ce)) {
-               zval_dtor(ret);
+       ZVAL_NULL(&ret);
+       if (SUCCESS != object_init_ex(&ret, ce)) {
+               zval_dtor(&ret);
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Unable to instantiate phar object when converting archive \"%s\"", phar->fname);
                return NULL;
        }
 
-       INIT_PZVAL(&arg1);
-       ZVAL_STRINGL(&arg1, phar->fname, phar->fname_len, 0);
+       ZVAL_STRINGL(&arg1, phar->fname, phar->fname_len);
 
        zend_call_method_with_1_params(&ret, ce, &ce->constructor, "__construct", NULL, &arg1);
-       return ret;
+       zval_ptr_dtor(&arg1);
+       return Z_OBJ(ret);
 }
 /* }}} */
 
-static zval *phar_convert_to_other(phar_archive_data *source, int convert, char *ext, php_uint32 flags TSRMLS_DC) /* {{{ */
+static zend_object *phar_convert_to_other(phar_archive_data *source, int convert, char *ext, php_uint32 flags TSRMLS_DC) /* {{{ */
 {
        phar_archive_data *phar;
        phar_entry_info *entry, newentry;
-       zval *ret;
+       zend_object *ret;
 
        /* invalidate phar cache */
        PHAR_G(last_phar) = NULL;
@@ -2260,22 +2243,15 @@ static zval *phar_convert_to_other(phar_archive_data *source, int convert, char
        phar->is_temporary_alias = source->is_temporary_alias;
        phar->alias = source->alias;
 
-       if (source->metadata) {
-               zval *t;
-
-               t = source->metadata;
-               ALLOC_ZVAL(phar->metadata);
-               *phar->metadata = *t;
-               zval_copy_ctor(phar->metadata);
-               Z_SET_REFCOUNT_P(phar->metadata, 1);
-
+       if (Z_TYPE(source->metadata) != IS_UNDEF) {
+               zval_copy_ctor(&phar->metadata);
                phar->metadata_len = 0;
        }
 
        /* first copy each file's uncompressed contents to a temporary file and set per-file flags */
        for (zend_hash_internal_pointer_reset(&source->manifest); SUCCESS == zend_hash_has_more_elements(&source->manifest); zend_hash_move_forward(&source->manifest)) {
 
-               if (FAILURE == zend_hash_get_current_data(&source->manifest, (void **) &entry)) {
+               if (NULL == (entry = zend_hash_get_current_data_ptr(&source->manifest))) {
                        zend_hash_destroy(&(phar->manifest));
                        php_stream_close(phar->fp);
                        efree(phar);
@@ -2296,7 +2272,7 @@ static zval *phar_convert_to_other(phar_archive_data *source, int convert, char
                        goto no_copy;
                }
 
-               newentry.metadata_str.c = 0;
+               newentry.metadata_str.s = NULL;
 
                if (FAILURE == phar_copy_file_contents(&newentry, phar->fp TSRMLS_CC)) {
                        zend_hash_destroy(&(phar->manifest));
@@ -2308,17 +2284,9 @@ static zval *phar_convert_to_other(phar_archive_data *source, int convert, char
 no_copy:
                newentry.filename = estrndup(newentry.filename, newentry.filename_len);
 
-               if (newentry.metadata) {
-                       zval *t;
-
-                       t = newentry.metadata;
-                       ALLOC_ZVAL(newentry.metadata);
-                       *newentry.metadata = *t;
-                       zval_copy_ctor(newentry.metadata);
-                       Z_SET_REFCOUNT_P(newentry.metadata, 1);
-
-                       newentry.metadata_str.c = NULL;
-                       newentry.metadata_str.len = 0;
+               if (Z_TYPE(newentry.metadata) != IS_UNDEF) {
+                       zval_copy_ctor(&newentry.metadata);
+                       newentry.metadata_str.s = NULL;
                }
 
                newentry.is_zip = phar->is_zip;
@@ -2332,7 +2300,7 @@ no_copy:
                newentry.phar = phar;
                newentry.old_flags = newentry.flags & ~PHAR_ENT_COMPRESSION_MASK; /* remove compression from old_flags */
                phar_set_inode(&newentry TSRMLS_CC);
-               zend_hash_add(&(phar->manifest), newentry.filename, newentry.filename_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
+               zend_hash_str_add_mem(&(phar->manifest), newentry.filename, newentry.filename_len, (void*)&newentry, sizeof(phar_entry_info));
                phar_add_virtual_dirs(phar, newentry.filename, newentry.filename_len TSRMLS_CC);
        }
 
@@ -2360,7 +2328,7 @@ PHP_METHOD(Phar, convertToExecutable)
        char *ext = NULL;
        int is_data, ext_len = 0;
        php_uint32 flags;
-       zval *ret;
+       zend_object *ret;
        /* a number that is not 0, 1 or 2 (Which is also Greg's birthday, so there) */
        long format = 9021976, method = 9021976;
        PHAR_ARCHIVE_OBJECT();
@@ -2446,7 +2414,7 @@ PHP_METHOD(Phar, convertToExecutable)
        phar_obj->arc.archive->is_data = is_data;
 
        if (ret) {
-               RETURN_ZVAL(ret, 1, 1);
+               ZVAL_OBJ(return_value, ret);
        } else {
                RETURN_NULL();
        }
@@ -2463,7 +2431,7 @@ PHP_METHOD(Phar, convertToData)
        char *ext = NULL;
        int is_data, ext_len = 0;
        php_uint32 flags;
-       zval *ret;
+       zend_object *ret;
        /* a number that is not 0, 1 or 2 (Which is also Greg's birthday so there) */
        long format = 9021976, method = 9021976;
        PHAR_ARCHIVE_OBJECT();
@@ -2548,7 +2516,7 @@ PHP_METHOD(Phar, convertToData)
        phar_obj->arc.archive->is_data = is_data;
 
        if (ret) {
-               RETURN_ZVAL(ret, 1, 1);
+               ZVAL_OBJ(return_value, ret);
        } else {
                RETURN_NULL();
        }
@@ -2632,8 +2600,8 @@ PHP_METHOD(Phar, delete)
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
                return;
        }
-       if (zend_hash_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
-               if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void**)&entry)) {
+       if (zend_hash_str_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
+               if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->arc.archive->manifest, fname, (uint) fname_len))) {
                        if (entry->is_deleted) {
                                /* entry is deleted, but has not been flushed to disk yet */
                                RETURN_TRUE;
@@ -2670,7 +2638,7 @@ PHP_METHOD(Phar, getAlias)
        }
 
        if (phar_obj->arc.archive->alias && phar_obj->arc.archive->alias != phar_obj->arc.archive->fname) {
-               RETURN_STRINGL(phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, 1);
+               RETURN_STRINGL(phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len);
        }
 }
 /* }}} */
@@ -2686,7 +2654,7 @@ PHP_METHOD(Phar, getPath)
                return;
        }
 
-       RETURN_STRINGL(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, 1);
+       RETURN_STRINGL(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len);
 }
 /* }}} */
 
@@ -2697,7 +2665,7 @@ PHP_METHOD(Phar, getPath)
 PHP_METHOD(Phar, setAlias)
 {
        char *alias, *error, *oldalias;
-       phar_archive_data **fd_ptr;
+       phar_archive_data *fd_ptr;
        int alias_len, oldalias_len, old_temp, readd = 0;
 
        PHAR_ARCHIVE_OBJECT();
@@ -2727,9 +2695,9 @@ PHP_METHOD(Phar, setAlias)
                if (alias_len == phar_obj->arc.archive->alias_len && memcmp(phar_obj->arc.archive->alias, alias, alias_len) == 0) {
                        RETURN_TRUE;
                }
-               if (alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void**)&fd_ptr)) {
-                       spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", alias, (*fd_ptr)->fname);
-                       if (SUCCESS == phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+               if (alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len))) {
+                       spprintf(&error, 0, "alias \"%s\" is already used for archive \"%s\" and cannot be used for other archives", alias, fd_ptr->fname);
+                       if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len TSRMLS_CC)) {
                                efree(error);
                                goto valid_alias;
                        }
@@ -2747,8 +2715,8 @@ valid_alias:
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
                        return;
                }
-               if (phar_obj->arc.archive->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len, (void**)&fd_ptr)) {
-                       zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len);
+               if (phar_obj->arc.archive->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len))) {
+                       zend_hash_str_del(&(PHAR_GLOBALS->phar_alias_map), phar_obj->arc.archive->alias, phar_obj->arc.archive->alias_len);
                        readd = 1;
                }
 
@@ -2772,13 +2740,13 @@ valid_alias:
                        phar_obj->arc.archive->is_temporary_alias = old_temp;
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "%s", error);
                        if (readd) {
-                               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), oldalias, oldalias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
+                               zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), oldalias, oldalias_len, phar_obj->arc.archive);
                        }
                        efree(error);
                        RETURN_FALSE;
                }
 
-               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(phar_obj->arc.archive), sizeof(phar_archive_data*), NULL);
+               zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, phar_obj->arc.archive);
 
                if (oldalias) {
                        efree(oldalias);
@@ -2802,7 +2770,7 @@ PHP_METHOD(Phar, getVersion)
                return;
        }
 
-       RETURN_STRING(phar_obj->arc.archive->version, 1);
+       RETURN_STRING(phar_obj->arc.archive->version);
 }
 /* }}} */
 
@@ -2896,7 +2864,7 @@ PHP_METHOD(Phar, setStub)
        }
 
        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zstub, &len) == SUCCESS) {
-               if ((php_stream_from_zval_no_verify(stream, &zstub)) != NULL) {
+               if ((php_stream_from_zval_no_verify(stream, zstub)) != NULL) {
                        if (len > 0) {
                                len = -len;
                        } else {
@@ -3134,9 +3102,9 @@ PHP_METHOD(Phar, getModified)
 }
 /* }}} */
 
-static int phar_set_compression(void *pDest, void *argument TSRMLS_DC) /* {{{ */
+static int phar_set_compression(zval *zv, void *argument TSRMLS_DC) /* {{{ */
 {
-       phar_entry_info *entry = (phar_entry_info *)pDest;
+       phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv);
        php_uint32 compress = *(php_uint32 *)argument;
 
        if (entry->is_deleted) {
@@ -3151,9 +3119,9 @@ static int phar_set_compression(void *pDest, void *argument TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-static int phar_test_compression(void *pDest, void *argument TSRMLS_DC) /* {{{ */
+static int phar_test_compression(zval *zv, void *argument TSRMLS_DC) /* {{{ */
 {
-       phar_entry_info *entry = (phar_entry_info *)pDest;
+       phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(zv);
 
        if (entry->is_deleted) {
                return ZEND_HASH_APPLY_KEEP;
@@ -3202,7 +3170,7 @@ PHP_METHOD(Phar, compress)
        char *ext = NULL;
        int ext_len = 0;
        php_uint32 flags;
-       zval *ret;
+       zend_object *ret;
        PHAR_ARCHIVE_OBJECT();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|s", &method, &ext, &ext_len) == FAILURE) {
@@ -3255,7 +3223,7 @@ PHP_METHOD(Phar, compress)
        }
 
        if (ret) {
-               RETURN_ZVAL(ret, 1, 1);
+               ZVAL_OBJ(return_value, ret);
        } else {
                RETURN_NULL();
        }
@@ -3269,7 +3237,7 @@ PHP_METHOD(Phar, decompress)
 {
        char *ext = NULL;
        int ext_len = 0;
-       zval *ret;
+       zend_object *ret;
        PHAR_ARCHIVE_OBJECT();
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext, &ext_len) == FAILURE) {
@@ -3295,7 +3263,7 @@ PHP_METHOD(Phar, decompress)
        }
 
        if (ret) {
-               RETURN_ZVAL(ret, 1, 1);
+               ZVAL_OBJ(return_value, ret);
        } else {
                RETURN_NULL();
        }
@@ -3462,14 +3430,14 @@ PHP_METHOD(Phar, copy)
                RETURN_FALSE;
        }
 
-       if (!zend_hash_exists(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len) || SUCCESS != zend_hash_find(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len, (void**)&oldentry) || oldentry->is_deleted) {
+       if (!zend_hash_str_exists(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len) || NULL == (oldentry = zend_hash_str_find_ptr(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len)) || oldentry->is_deleted) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
                        "file \"%s\" cannot be copied to file \"%s\", file does not exist in %s", oldfile, newfile, phar_obj->arc.archive->fname);
                RETURN_FALSE;
        }
 
-       if (zend_hash_exists(&phar_obj->arc.archive->manifest, newfile, (uint) newfile_len)) {
-               if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, newfile, (uint) newfile_len, (void**)&temp) || !temp->is_deleted) {
+       if (zend_hash_str_exists(&phar_obj->arc.archive->manifest, newfile, (uint) newfile_len)) {
+               if (NULL != (temp = zend_hash_str_find_ptr(&phar_obj->arc.archive->manifest, newfile, (uint) newfile_len)) || !temp->is_deleted) {
                        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
                                "file \"%s\" cannot be copied to file \"%s\", file must not already exist in phar %s", oldfile, newfile, phar_obj->arc.archive->fname);
                        RETURN_FALSE;
@@ -3488,22 +3456,14 @@ PHP_METHOD(Phar, copy)
                        return;
                }
                /* re-populate with copied-on-write entry */
-               zend_hash_find(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len, (void**)&oldentry);
+               oldentry = zend_hash_str_find_ptr(&phar_obj->arc.archive->manifest, oldfile, (uint) oldfile_len);
        }
 
        memcpy((void *) &newentry, oldentry, sizeof(phar_entry_info));
 
-       if (newentry.metadata) {
-               zval *t;
-
-               t = newentry.metadata;
-               ALLOC_ZVAL(newentry.metadata);
-               *newentry.metadata = *t;
-               zval_copy_ctor(newentry.metadata);
-               Z_SET_REFCOUNT_P(newentry.metadata, 1);
-
-               newentry.metadata_str.c = NULL;
-               newentry.metadata_str.len = 0;
+       if (Z_TYPE(newentry.metadata) != IS_UNDEF) {
+               zval_copy_ctor(&newentry.metadata);
+               newentry.metadata_str.s = NULL;
        }
 
        newentry.filename = estrndup(newfile, newfile_len);
@@ -3520,7 +3480,7 @@ PHP_METHOD(Phar, copy)
                }
        }
 
-       zend_hash_add(&oldentry->phar->manifest, newfile, newfile_len, (void*)&newentry, sizeof(phar_entry_info), NULL);
+       zend_hash_str_add_mem(&oldentry->phar->manifest, newfile, newfile_len, &newentry, sizeof(phar_entry_info));
        phar_obj->arc.archive->is_modified = 1;
        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
 
@@ -3548,8 +3508,8 @@ PHP_METHOD(Phar, offsetExists)
                return;
        }
 
-       if (zend_hash_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
-               if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void**)&entry)) {
+       if (zend_hash_str_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
+               if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->arc.archive->manifest, fname, (uint) fname_len))) {
                        if (entry->is_deleted) {
                                /* entry is deleted, but has not been flushed to disk yet */
                                RETURN_FALSE;
@@ -3562,7 +3522,7 @@ PHP_METHOD(Phar, offsetExists)
                }
                RETURN_TRUE;
        } else {
-               if (zend_hash_exists(&phar_obj->arc.archive->virtual_dirs, fname, (uint) fname_len)) {
+               if (zend_hash_str_exists(&phar_obj->arc.archive->virtual_dirs, fname, (uint) fname_len)) {
                        RETURN_TRUE;
                }
                RETURN_FALSE;
@@ -3577,7 +3537,7 @@ PHP_METHOD(Phar, offsetGet)
 {
        char *fname, *error;
        int fname_len;
-       zval *zfname;
+       zval zfname;
        phar_entry_info *entry;
        PHAR_ARCHIVE_OBJECT();
 
@@ -3610,9 +3570,8 @@ PHP_METHOD(Phar, offsetGet)
                }
 
                fname_len = spprintf(&fname, 0, "phar://%s/%s", phar_obj->arc.archive->fname, fname);
-               MAKE_STD_ZVAL(zfname);
-               ZVAL_STRINGL(zfname, fname, fname_len, 0);
-               spl_instantiate_arg_ex1(phar_obj->spl.info_class, return_value, zfname TSRMLS_CC);
+               ZVAL_STRINGL(&zfname, fname, fname_len);
+               spl_instantiate_arg_ex1(phar_obj->spl.info_class, return_value, &zfname TSRMLS_CC);
                zval_ptr_dtor(&zfname);
        }
 }
@@ -3653,7 +3612,7 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, int filenam
                                        return;
                                }
                        } else {
-                               if (!(php_stream_from_zval_no_verify(contents_file, &zresource))) {
+                               if (!(php_stream_from_zval_no_verify(contents_file, zresource))) {
                                        zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", filename);
                                        return;
                                }
@@ -3772,8 +3731,8 @@ PHP_METHOD(Phar, offsetUnset)
                return;
        }
 
-       if (zend_hash_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
-               if (SUCCESS == zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void**)&entry)) {
+       if (zend_hash_str_exists(&phar_obj->arc.archive->manifest, fname, (uint) fname_len)) {
+               if (NULL != (entry = zend_hash_str_find_ptr(&phar_obj->arc.archive->manifest, fname, (uint) fname_len))) {
                        if (entry->is_deleted) {
                                /* entry is deleted, but has not been flushed to disk yet */
                                return;
@@ -3785,7 +3744,7 @@ PHP_METHOD(Phar, offsetUnset)
                                        return;
                                }
                                /* re-populate entry after copy on write */
-                               zend_hash_find(&phar_obj->arc.archive->manifest, fname, (uint) fname_len, (void **)&entry);
+                               entry = zend_hash_str_find_ptr(&phar_obj->arc.archive->manifest, fname, (uint) fname_len);
                        }
                        entry->is_modified = 0;
                        entry->is_deleted = 1;
@@ -3836,7 +3795,7 @@ PHP_METHOD(Phar, addFile)
        char *fname, *localname = NULL;
        int fname_len, localname_len = 0;
        php_stream *resource;
-       zval *zresource;
+       zval zresource;
 
        PHAR_ARCHIVE_OBJECT();
 
@@ -3866,10 +3825,9 @@ PHP_METHOD(Phar, addFile)
                fname_len = localname_len;
        }
 
-       MAKE_STD_ZVAL(zresource);
-       php_stream_to_zval(resource, zresource);
-       phar_add_file(&(phar_obj->arc.archive), fname, fname_len, NULL, 0, zresource TSRMLS_CC);
-       efree(zresource);
+       php_stream_to_zval(resource, &zresource);
+       phar_add_file(&(phar_obj->arc.archive), fname, fname_len, NULL, 0, &zresource TSRMLS_CC);
+       zval_ptr_dtor(&zresource);
        php_stream_close(resource);
 }
 /* }}} */
@@ -3911,7 +3869,7 @@ PHP_METHOD(Phar, getStub)
 
        if (phar_obj->arc.archive->is_tar || phar_obj->arc.archive->is_zip) {
 
-               if (SUCCESS == zend_hash_find(&(phar_obj->arc.archive->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1, (void **)&stub)) {
+               if (NULL != (stub = zend_hash_str_find_ptr(&(phar_obj->arc.archive->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1))) {
                        if (phar_obj->arc.archive->fp && !phar_obj->arc.archive->is_brandnew && !(stub->flags & PHAR_ENT_COMPRESSION_MASK)) {
                                fp = phar_obj->arc.archive->fp;
                        } else {
@@ -3945,7 +3903,7 @@ PHP_METHOD(Phar, getStub)
                        len = stub->uncompressed_filesize;
                        goto carry_on;
                } else {
-                       RETURN_STRINGL("", 0, 1);
+                       RETURN_EMPTY_STRING();
                }
        }
        len = phar_obj->arc.archive->halt_offset;
@@ -3986,7 +3944,9 @@ carry_on:
        }
 
        buf[len] = '\0';
-       RETURN_STRINGL(buf, len, 0);
+       // TODO: avoid reallocation ???
+       RETVAL_STRINGL(buf, len);
+       efree(buf);
 }
 /* }}}*/
 
@@ -3997,7 +3957,7 @@ PHP_METHOD(Phar, hasMetadata)
 {
        PHAR_ARCHIVE_OBJECT();
 
-       RETURN_BOOL(phar_obj->arc.archive->metadata != NULL);
+       RETURN_BOOL(Z_TYPE(phar_obj->arc.archive->metadata) != IS_UNDEF);
 }
 /* }}} */
 
@@ -4012,16 +3972,16 @@ PHP_METHOD(Phar, getMetadata)
                return;
        }
 
-       if (phar_obj->arc.archive->metadata) {
+       if (Z_TYPE(phar_obj->arc.archive->metadata) != IS_UNDEF) {
                if (phar_obj->arc.archive->is_persistent) {
-                       zval *ret;
-                       char *buf = estrndup((char *) phar_obj->arc.archive->metadata, phar_obj->arc.archive->metadata_len);
+                       zval ret;
+                       char *buf = estrndup((char *) Z_PTR(phar_obj->arc.archive->metadata), phar_obj->arc.archive->metadata_len);
                        /* assume success, we would have failed before */
                        phar_parse_metadata(&buf, &ret, phar_obj->arc.archive->metadata_len TSRMLS_CC);
                        efree(buf);
-                       RETURN_ZVAL(ret, 0, 1);
+                       RETURN_ZVAL(&ret, 0, 1);
                }
-               RETURN_ZVAL(phar_obj->arc.archive->metadata, 1, 0);
+               RETURN_ZVAL(&phar_obj->arc.archive->metadata, 1, 0);
        }
 }
 /* }}} */
@@ -4049,13 +4009,12 @@ PHP_METHOD(Phar, setMetadata)
                zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar \"%s\" is persistent, unable to copy on write", phar_obj->arc.archive->fname);
                return;
        }
-       if (phar_obj->arc.archive->metadata) {
+       if (Z_TYPE(phar_obj->arc.archive->metadata) != IS_UNDEF) {
                zval_ptr_dtor(&phar_obj->arc.archive->metadata);
-               phar_obj->arc.archive->metadata = NULL;
+               ZVAL_UNDEF(&phar_obj->arc.archive->metadata);
        }
 
-       MAKE_STD_ZVAL(phar_obj->arc.archive->metadata);
-       ZVAL_ZVAL(phar_obj->arc.archive->metadata, metadata, 1, 0);
+       ZVAL_ZVAL(&phar_obj->arc.archive->metadata, metadata, 1, 0);
        phar_obj->arc.archive->is_modified = 1;
        phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
 
@@ -4080,9 +4039,9 @@ PHP_METHOD(Phar, delMetadata)
                return;
        }
 
-       if (phar_obj->arc.archive->metadata) {
+       if (Z_TYPE(phar_obj->arc.archive->metadata) != IS_UNDEF) {
                zval_ptr_dtor(&phar_obj->arc.archive->metadata);
-               phar_obj->arc.archive->metadata = NULL;
+               ZVAL_UNDEF(&phar_obj->arc.archive->metadata);
                phar_obj->arc.archive->is_modified = 1;
                phar_flush(phar_obj->arc.archive, 0, 0, 0, &error TSRMLS_CC);
 
@@ -4325,9 +4284,9 @@ PHP_METHOD(Phar, extractTo)
                                        RETURN_FALSE;
                                }
                                for (i = 0; i < nelems; i++) {
-                                       zval **zval_file;
-                                       if (zend_hash_index_find(Z_ARRVAL_P(zval_files), i, (void **) &zval_file) == SUCCESS) {
-                                               switch (Z_TYPE_PP(zval_file)) {
+                                       zval *zval_file;
+                                       if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(zval_files), i)) != NULL) {
+                                               switch (Z_TYPE_P(zval_file)) {
                                                        case IS_STRING:
                                                                break;
                                                        default:
@@ -4335,9 +4294,9 @@ PHP_METHOD(Phar, extractTo)
                                                                        "Invalid argument, array of filenames to extract contains non-string value");
                                                                return;
                                                }
-                                               if (FAILURE == zend_hash_find(&phar_obj->arc.archive->manifest, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), (void **)&entry)) {
+                                               if (NULL == (entry = zend_hash_find_ptr(&phar_obj->arc.archive->manifest, Z_STR_P(zval_file)))) {
                                                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
-                                                               "Phar Error: attempted to extract non-existent file \"%s\" from phar \"%s\"", Z_STRVAL_PP(zval_file), phar_obj->arc.archive->fname);
+                                                               "Phar Error: attempted to extract non-existent file \"%s\" from phar \"%s\"", Z_STRVAL_P(zval_file), phar_obj->arc.archive->fname);
                                                }
                                                if (FAILURE == phar_extract_file(overwrite, entry, pathto, pathto_len, &error TSRMLS_CC)) {
                                                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
@@ -4354,7 +4313,7 @@ PHP_METHOD(Phar, extractTo)
                                return;
                }
 
-               if (FAILURE == zend_hash_find(&phar_obj->arc.archive->manifest, filename, filename_len, (void **)&entry)) {
+               if (NULL == (entry = zend_hash_str_find_ptr(&phar_obj->arc.archive->manifest, filename, filename_len))) {
                        zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC,
                                "Phar Error: attempted to extract non-existent file \"%s\" from phar \"%s\"", filename, phar_obj->arc.archive->fname);
                        return;
@@ -4379,7 +4338,7 @@ all_files:
                zend_hash_has_more_elements(&phar->manifest) == SUCCESS;
                zend_hash_move_forward(&phar->manifest)) {
 
-                       if (zend_hash_get_current_data(&phar->manifest, (void **)&entry) == FAILURE) {
+                       if ((entry = zend_hash_get_current_data_ptr(&phar->manifest)) == NULL) {
                                continue;
                        }
 
@@ -4412,7 +4371,7 @@ PHP_METHOD(PharFileInfo, __construct)
                return;
        }
 
-       entry_obj = (phar_entry_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       entry_obj = (phar_entry_object*)Z_OBJ_P(getThis());
 
        if (entry_obj->ent.entry) {
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Cannot call constructor twice");
@@ -4452,16 +4411,17 @@ PHP_METHOD(PharFileInfo, __construct)
 
        entry_obj->ent.entry = entry_info;
 
-       INIT_PZVAL(&arg1);
-       ZVAL_STRINGL(&arg1, fname, fname_len, 0);
+       ZVAL_STRINGL(&arg1, fname, fname_len);
 
-       zend_call_method_with_1_params(&zobj, Z_OBJCE_P(zobj), 
+       zend_call_method_with_1_params(zobj, Z_OBJCE_P(zobj), 
                &spl_ce_SplFileInfo->constructor, "__construct", NULL, &arg1);
+
+       zval_ptr_dtor(&arg1);
 }
 /* }}} */
 
 #define PHAR_ENTRY_OBJECT() \
-       phar_entry_object *entry_obj = (phar_entry_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
+       phar_entry_object *entry_obj = (phar_entry_object*)Z_OBJ_P(getThis()); \
        if (!entry_obj->ent.entry) { \
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
                        "Cannot call method on an uninitialized PharFileInfo object"); \
@@ -4473,7 +4433,7 @@ PHP_METHOD(PharFileInfo, __construct)
  */
 PHP_METHOD(PharFileInfo, __destruct)
 {
-       phar_entry_object *entry_obj = (phar_entry_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
+       phar_entry_object *entry_obj = (phar_entry_object*)Z_OBJ_P(getThis());
 
        if (entry_obj->ent.entry && entry_obj->ent.entry->is_temp_dir) {
                if (entry_obj->ent.entry->filename) {
@@ -4617,7 +4577,7 @@ PHP_METHOD(PharFileInfo, chmod)
                        return;
                }
                /* re-populate after copy-on-write */
-               zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
+               entry_obj->ent.entry = zend_hash_str_find_ptr(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len);
        }
        /* clear permissions */
        entry_obj->ent.entry->flags &= ~PHAR_ENT_PERM_MASK;
@@ -4659,7 +4619,7 @@ PHP_METHOD(PharFileInfo, hasMetadata)
                return;
        }
 
-       RETURN_BOOL(entry_obj->ent.entry->metadata != NULL);
+       RETURN_BOOL(Z_TYPE(entry_obj->ent.entry->metadata) != IS_UNDEF);
 }
 /* }}} */
 
@@ -4674,16 +4634,16 @@ PHP_METHOD(PharFileInfo, getMetadata)
                return;
        }
 
-       if (entry_obj->ent.entry->metadata) {
+       if (Z_TYPE(entry_obj->ent.entry->metadata) != IS_UNDEF) {
                if (entry_obj->ent.entry->is_persistent) {
-                       zval *ret;
-                       char *buf = estrndup((char *) entry_obj->ent.entry->metadata, entry_obj->ent.entry->metadata_len);
+                       zval ret;
+                       char *buf = estrndup((char *) Z_PTR(entry_obj->ent.entry->metadata), entry_obj->ent.entry->metadata_len);
                        /* assume success, we would have failed before */
                        phar_parse_metadata(&buf, &ret, entry_obj->ent.entry->metadata_len TSRMLS_CC);
                        efree(buf);
-                       RETURN_ZVAL(ret, 0, 1);
+                       RETURN_ZVAL(&ret, 0, 1);
                }
-               RETURN_ZVAL(entry_obj->ent.entry->metadata, 1, 0);
+               RETURN_ZVAL(&entry_obj->ent.entry->metadata, 1, 0);
        }
 }
 /* }}} */
@@ -4721,15 +4681,14 @@ PHP_METHOD(PharFileInfo, setMetadata)
                        return;
                }
                /* re-populate after copy-on-write */
-               zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
+               entry_obj->ent.entry = zend_hash_str_find_ptr(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len);
        }
-       if (entry_obj->ent.entry->metadata) {
+       if (Z_TYPE(entry_obj->ent.entry->metadata) != IS_UNDEF) {
                zval_ptr_dtor(&entry_obj->ent.entry->metadata);
-               entry_obj->ent.entry->metadata = NULL;
+               ZVAL_UNDEF(&entry_obj->ent.entry->metadata);
        }
 
-       MAKE_STD_ZVAL(entry_obj->ent.entry->metadata);
-       ZVAL_ZVAL(entry_obj->ent.entry->metadata, metadata, 1, 0);
+       ZVAL_ZVAL(&entry_obj->ent.entry->metadata, metadata, 1, 0);
 
        entry_obj->ent.entry->is_modified = 1;
        entry_obj->ent.entry->phar->is_modified = 1;
@@ -4766,7 +4725,7 @@ PHP_METHOD(PharFileInfo, delMetadata)
                return;
        }
 
-       if (entry_obj->ent.entry->metadata) {
+       if (Z_TYPE(entry_obj->ent.entry->metadata) != IS_UNDEF) {
                if (entry_obj->ent.entry->is_persistent) {
                        phar_archive_data *phar = entry_obj->ent.entry->phar;
 
@@ -4775,10 +4734,10 @@ PHP_METHOD(PharFileInfo, delMetadata)
                                return;
                        }
                        /* re-populate after copy-on-write */
-                       zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
+                       entry_obj->ent.entry = zend_hash_str_find_ptr(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len);
                }
                zval_ptr_dtor(&entry_obj->ent.entry->metadata);
-               entry_obj->ent.entry->metadata = NULL;
+               ZVAL_UNDEF(&entry_obj->ent.entry->metadata);
                entry_obj->ent.entry->is_modified = 1;
                entry_obj->ent.entry->phar->is_modified = 1;
 
@@ -4806,6 +4765,7 @@ PHP_METHOD(PharFileInfo, getContent)
        char *error;
        php_stream *fp;
        phar_entry_info *link;
+       zend_string *str;
 
        PHAR_ENTRY_OBJECT();
        
@@ -4839,11 +4799,11 @@ PHP_METHOD(PharFileInfo, getContent)
        }
 
        phar_seek_efp(link, 0, SEEK_SET, 0, 0 TSRMLS_CC);
-       Z_TYPE_P(return_value) = IS_STRING;
-       Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0);
-
-       if (!Z_STRVAL_P(return_value)) {
-               Z_STRVAL_P(return_value) = estrndup("", 0);
+       str = php_stream_copy_to_mem(fp, link->uncompressed_filesize, 0);
+       if (str) {
+               RETURN_STR(str);
+       } else {
+               RETURN_EMPTY_STRING();
        }
 }
 /* }}} */
@@ -4893,7 +4853,7 @@ PHP_METHOD(PharFileInfo, compress)
                        return;
                }
                /* re-populate after copy-on-write */
-               zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
+               entry_obj->ent.entry = zend_hash_str_find_ptr(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len);
        }
        switch (method) {
                case PHAR_ENT_COMPRESSED_GZ:
@@ -5029,7 +4989,7 @@ PHP_METHOD(PharFileInfo, decompress)
                        return;
                }
                /* re-populate after copy-on-write */
-               zend_hash_find(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len, (void **)&entry_obj->ent.entry);
+               entry_obj->ent.entry = zend_hash_str_find_ptr(&phar->manifest, entry_obj->ent.entry->filename, entry_obj->ent.entry->filename_len);
        }
        if (!entry_obj->ent.entry->fp) {
                if (FAILURE == phar_open_archive_fp(entry_obj->ent.entry->phar TSRMLS_CC)) {
index c38c20d63521c3223f87eb423964fddd4b8199b0..44ee853f65736ac2b13d80b657b7cac9b307b921 100644 (file)
@@ -101,12 +101,12 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const
                }
 #endif
        if (mode[0] == 'w' || (mode[0] == 'r' && mode[1] == '+')) {
-               phar_archive_data **pphar = NULL, *phar;
+               phar_archive_data *pphar = NULL, *phar;
 
-               if (PHAR_GLOBALS->request_init && PHAR_GLOBALS->phar_fname_map.arHash && FAILURE == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) {
+               if (PHAR_GLOBALS->request_init && PHAR_GLOBALS->phar_fname_map.arHash && NULL == (pphar = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len))) {
                        pphar = NULL;
                }
-               if (PHAR_G(readonly) && (!pphar || !(*pphar)->is_data)) {
+               if (PHAR_G(readonly) && (!pphar || !pphar->is_data)) {
                        if (!(options & PHP_STREAM_URL_STAT_QUIET)) {
                                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: write operations disabled by the php.ini setting phar.readonly");
                        }
@@ -164,7 +164,7 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha
        HashTable *pharcontext;
        php_url *resource = NULL;
        php_stream *fpf;
-       zval **pzoption, *metadata;
+       zval *pzoption, *metadata;
        uint host_len;
 
        if ((resource = phar_parse_url(wrapper, path, mode, options TSRMLS_CC)) == NULL) {
@@ -208,26 +208,25 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha
                php_url_free(resource);
                efree(internal_file);
 
-               if (context && context->options && zend_hash_find(HASH_OF(context->options), "phar", sizeof("phar"), (void**)&pzoption) == SUCCESS) {
-                       pharcontext = HASH_OF(*pzoption);
+               if (context && Z_TYPE(context->options) != IS_UNDEF && (pzoption = zend_hash_str_find(HASH_OF(&context->options), "phar", sizeof("phar")-1)) != NULL) {
+                       pharcontext = HASH_OF(pzoption);
                        if (idata->internal_file->uncompressed_filesize == 0
                                && idata->internal_file->compressed_filesize == 0
-                               && zend_hash_find(pharcontext, "compress", sizeof("compress"), (void**)&pzoption) == SUCCESS
-                               && Z_TYPE_PP(pzoption) == IS_LONG
-                               && (Z_LVAL_PP(pzoption) & ~PHAR_ENT_COMPRESSION_MASK) == 0
+                               && (pzoption = zend_hash_str_find(pharcontext, "compress", sizeof("compress")-1)) != NULL
+                               && Z_TYPE_P(pzoption) == IS_LONG
+                               && (Z_LVAL_P(pzoption) & ~PHAR_ENT_COMPRESSION_MASK) == 0
                        ) {
                                idata->internal_file->flags &= ~PHAR_ENT_COMPRESSION_MASK;
-                               idata->internal_file->flags |= Z_LVAL_PP(pzoption);
+                               idata->internal_file->flags |= Z_LVAL_P(pzoption);
                        }
-                       if (zend_hash_find(pharcontext, "metadata", sizeof("metadata"), (void**)&pzoption) == SUCCESS) {
-                               if (idata->internal_file->metadata) {
+                       if ((pzoption = zend_hash_str_find(pharcontext, "metadata", sizeof("metadata")-1)) != NULL) {
+                               if (Z_TYPE(idata->internal_file->metadata) != IS_UNDEF) {
                                        zval_ptr_dtor(&idata->internal_file->metadata);
-                                       idata->internal_file->metadata = NULL;
+                                       ZVAL_UNDEF(&idata->internal_file->metadata);
                                }
 
-                               MAKE_STD_ZVAL(idata->internal_file->metadata);
-                               metadata = *pzoption;
-                               ZVAL_ZVAL(idata->internal_file->metadata, metadata, 1, 0);
+                               metadata = pzoption;
+                               ZVAL_ZVAL(&idata->internal_file->metadata, metadata, 1, 0);
                                idata->phar->is_modified = 1;
                        }
                }
@@ -615,41 +614,35 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f
        }
        internal_file_len = strlen(internal_file);
        /* search through the manifest of files, and if we have an exact match, it's a file */
-       if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, internal_file_len, (void**)&entry)) {
+       if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len))) {
                phar_dostat(phar, entry, ssb, 0 TSRMLS_CC);
                php_url_free(resource);
                return SUCCESS;
        }
-       if (zend_hash_exists(&(phar->virtual_dirs), internal_file, internal_file_len)) {
+       if (zend_hash_str_exists(&(phar->virtual_dirs), internal_file, internal_file_len)) {
                phar_dostat(phar, NULL, ssb, 1 TSRMLS_CC);
                php_url_free(resource);
                return SUCCESS;
        }
        /* check for mounted directories */
        if (phar->mounted_dirs.arHash && zend_hash_num_elements(&phar->mounted_dirs)) {
-               char *str_key;
-               ulong unused;
-               uint keylen;
-               HashPosition pos;
+               zend_string *str_key;
 
-               for (zend_hash_internal_pointer_reset_ex(&phar->mounted_dirs, &pos);
-                       HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->mounted_dirs, &str_key, &keylen, &unused, 0, &pos);
-                       zend_hash_move_forward_ex(&phar->mounted_dirs, &pos)
-               ) {
-                       if ((int)keylen >= internal_file_len || strncmp(str_key, internal_file, keylen)) {
+               ZEND_HASH_FOREACH_STR_KEY(&phar->mounted_dirs, str_key) {
+                       if ((int)str_key->len >= internal_file_len || strncmp(str_key->val, internal_file, str_key->len)) {
                                continue;
                        } else {
                                char *test;
                                int test_len;
                                php_stream_statbuf ssbi;
 
-                               if (SUCCESS != zend_hash_find(&phar->manifest, str_key, keylen, (void **) &entry)) {
+                               if (NULL == (entry = zend_hash_find_ptr(&phar->manifest, str_key))) {
                                        goto free_resource;
                                }
                                if (!entry->tmp || !entry->is_mounted) {
                                        goto free_resource;
                                }
-                               test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, internal_file + keylen);
+                               test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, internal_file + str_key->len);
                                if (SUCCESS != php_stream_stat_path(test, &ssbi)) {
                                        efree(test);
                                        continue;
@@ -660,14 +653,14 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f
                                        goto free_resource;
                                }
                                efree(test);
-                               if (SUCCESS != zend_hash_find(&phar->manifest, internal_file, internal_file_len, (void**)&entry)) {
+                               if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, internal_file, internal_file_len))) {
                                        goto free_resource;
                                }
                                phar_dostat(phar, entry, ssb, 0 TSRMLS_CC);
                                php_url_free(resource);
                                return SUCCESS;
                        }
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 free_resource:
        php_url_free(resource);
@@ -708,9 +701,7 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int
        host_len = strlen(resource->host);
        phar_request_initialize(TSRMLS_C);
 
-       if (FAILURE == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), resource->host, host_len, (void **) &pphar)) {
-               pphar = NULL;
-       }
+       pphar = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), resource->host, host_len);
        if (PHAR_G(readonly) && (!pphar || !(*pphar)->is_data)) {
                php_url_free(resource);
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: write operations disabled by the php.ini setting phar.readonly");
@@ -852,7 +843,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
                return 0;
        }
 
-       if (SUCCESS == zend_hash_find(&(phar->manifest), resource_from->path+1, strlen(resource_from->path)-1, (void **)&entry)) {
+       if (NULL != (entry = zend_hash_str_find_ptr(&(phar->manifest), resource_from->path+1, strlen(resource_from->path)-1))) {
                phar_entry_info new, *source;
 
                /* perform rename magic */
@@ -867,12 +858,12 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
                /* mark the old one for deletion */
                entry->is_deleted = 1;
                entry->fp = NULL;
-               entry->metadata = 0;
+               ZVAL_UNDEF(&entry->metadata);
                entry->link = entry->tmp = NULL;
                source = entry;
 
                /* add to the manifest, and then store the pointer to the new guy in entry */
-               zend_hash_add(&(phar->manifest), resource_to->path+1, strlen(resource_to->path)-1, (void **)&new, sizeof(phar_entry_info), (void **) &entry);
+               entry = zend_hash_str_add_mem(&(phar->manifest), resource_to->path+1, strlen(resource_to->path)-1, (void **)&new, sizeof(phar_entry_info));
 
                entry->filename = estrdup(resource_to->path+1);
                if (FAILURE == phar_copy_entry_fp(source, entry, &error TSRMLS_CC)) {
@@ -880,7 +871,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
                        php_url_free(resource_to);
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "phar error: cannot rename \"%s\" to \"%s\": %s", url_from, url_to, error);
                        efree(error);
-                       zend_hash_del(&(phar->manifest), entry->filename, strlen(entry->filename));
+                       zend_hash_str_del(&(phar->manifest), entry->filename, strlen(entry->filename));
                        return 0;
                }
                is_modified = 1;
@@ -888,7 +879,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
                entry->filename_len = strlen(entry->filename);
                is_dir = entry->is_dir;
        } else {
-               is_dir = zend_hash_exists(&(phar->virtual_dirs), resource_from->path+1, strlen(resource_from->path)-1);
+               is_dir = zend_hash_str_exists(&(phar->virtual_dirs), resource_from->path+1, strlen(resource_from->path)-1);
                if (!is_dir) {
                        /* file does not exist */
                        php_url_free(resource_from);
@@ -902,74 +893,73 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
        /* Rename directory. Update all nested paths */
        if (is_dir) {
                int key_type;
-               char *str_key, *new_str_key;
-               uint key_len, new_key_len;
+               zend_string *str_key;
+               zend_string *new_str_key;
                ulong unused;
                uint from_len = strlen(resource_from->path+1);
                uint to_len = strlen(resource_to->path+1);
 
                for (zend_hash_internal_pointer_reset(&phar->manifest);
-                       HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &str_key, &key_len, &unused, 0, NULL)) &&
-                       SUCCESS == zend_hash_get_current_data(&phar->manifest, (void **) &entry);
+                       HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &str_key, &unused, 0, &phar->manifest.nInternalPointer)) &&
+                       NULL != (entry = zend_hash_get_current_data_ptr(&phar->manifest));
                        zend_hash_move_forward(&phar->manifest)
                ) {
                        if (!entry->is_deleted &&
-                               key_len > from_len &&
-                               memcmp(str_key, resource_from->path+1, from_len) == 0 &&
-                               IS_SLASH(str_key[from_len])) {
+                               str_key->len > from_len &&
+                               memcmp(str_key->val, resource_from->path+1, from_len) == 0 &&
+                               IS_SLASH(str_key->val[from_len])) {
 
-                               new_key_len = key_len + to_len - from_len;
-                               new_str_key = emalloc(new_key_len+1);
-                               memcpy(new_str_key, resource_to->path + 1, to_len);
-                               memcpy(new_str_key + to_len, str_key + from_len, key_len - from_len);
-                               new_str_key[new_key_len] = 0;
+                               new_str_key = STR_ALLOC(str_key->len + to_len - from_len, 0);
+                               memcpy(new_str_key->val, resource_to->path + 1, to_len);
+                               memcpy(new_str_key->val + to_len, str_key->val + from_len, str_key->len - from_len);
+                               new_str_key->val[new_str_key->len] = 0;
 
                                is_modified = 1;
                                entry->is_modified = 1;
                                efree(entry->filename);
-                               entry->filename = new_str_key;
-                               entry->filename_len = new_key_len;
+                               // TODO: avoid reallocation (make entry->filename zend_string*)
+                               entry->filename = estrndup(new_str_key->val, new_str_key->len);
+                               entry->filename_len = new_str_key->len;
 
-                               zend_hash_update_current_key_ex(&phar->manifest, key_type, new_str_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL);
+                               zend_hash_update_current_key_ex(&phar->manifest, key_type, new_str_key, 0, HASH_UPDATE_KEY_ANYWAY);
+                               STR_RELEASE(new_str_key);
                        }
                }
 
                for (zend_hash_internal_pointer_reset(&phar->virtual_dirs);
-                       HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &str_key, &key_len, &unused, 0, NULL));
+                       HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &str_key, &unused, 0, &phar->virtual_dirs.nInternalPointer));
                        zend_hash_move_forward(&phar->virtual_dirs)
                ) {
-                       if (key_len >= from_len &&
-                               memcmp(str_key, resource_from->path+1, from_len) == 0 &&
-                               (key_len == from_len || IS_SLASH(str_key[from_len]))) {
-
-                               new_key_len = key_len + to_len - from_len;
-                               new_str_key = emalloc(new_key_len+1);
-                               memcpy(new_str_key, resource_to->path + 1, to_len);
-                               memcpy(new_str_key + to_len, str_key + from_len, key_len - from_len);
-                               new_str_key[new_key_len] = 0;
-
-                               zend_hash_update_current_key_ex(&phar->virtual_dirs, key_type, new_str_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL);
-                               efree(new_str_key);
+                       if (str_key->len >= from_len &&
+                               memcmp(str_key->val, resource_from->path+1, from_len) == 0 &&
+                               (str_key->len == from_len || IS_SLASH(str_key->val[from_len]))) {
+
+                               new_str_key = STR_ALLOC(str_key->len + to_len - from_len, 0);
+                               memcpy(new_str_key->val, resource_to->path + 1, to_len);
+                               memcpy(new_str_key->val + to_len, str_key->val + from_len, str_key->len - from_len);
+                               new_str_key->val[new_str_key->len] = 0;
+
+                               zend_hash_update_current_key_ex(&phar->virtual_dirs, key_type, new_str_key, 0, HASH_UPDATE_KEY_ANYWAY);
+                               STR_RELEASE(new_str_key);
                        }
                }
 
                for (zend_hash_internal_pointer_reset(&phar->mounted_dirs);
-                       HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->mounted_dirs, &str_key, &key_len, &unused, 0, NULL)) &&
-                       SUCCESS == zend_hash_get_current_data(&phar->mounted_dirs, (void **) &entry);
+                       HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->mounted_dirs, &str_key, &unused, 0, &phar->mounted_dirs.nInternalPointer)) &&
+                       NULL != (entry = zend_hash_get_current_data_ptr(&phar->mounted_dirs));
                        zend_hash_move_forward(&phar->mounted_dirs)
                ) {
-                       if (key_len >= from_len &&
-                               memcmp(str_key, resource_from->path+1, from_len) == 0 &&
-                               (key_len == from_len || IS_SLASH(str_key[from_len]))) {
-
-                               new_key_len = key_len + to_len - from_len;
-                               new_str_key = emalloc(new_key_len+1);
-                               memcpy(new_str_key, resource_to->path + 1, to_len);
-                               memcpy(new_str_key + to_len, str_key + from_len, key_len - from_len);
-                               new_str_key[new_key_len] = 0;
-
-                               zend_hash_update_current_key_ex(&phar->mounted_dirs, key_type, new_str_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL);
-                               efree(new_str_key);
+                       if (str_key->len >= from_len &&
+                               memcmp(str_key->val, resource_from->path+1, from_len) == 0 &&
+                               (str_key->len == from_len || IS_SLASH(str_key->val[from_len]))) {
+
+                               new_str_key = STR_ALLOC(str_key->len + to_len - from_len, 0);
+                               memcpy(new_str_key->val, resource_to->path + 1, to_len);
+                               memcpy(new_str_key->val + to_len, str_key->val + from_len, str_key->len - from_len);
+                               new_str_key->val[new_str_key->len] = 0;
+
+                               zend_hash_update_current_key_ex(&phar->mounted_dirs, key_type, new_str_key, 0, HASH_UPDATE_KEY_ANYWAY);
+                               STR_RELEASE(new_str_key);
                        }
                }
        }
index 17b537dae035bf3e0009df6b5af3a0723e11e24b..c22b1df1d857b52c543ece698f9f2af5c3f5eabe 100644 (file)
@@ -179,11 +179,12 @@ static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRM
 
        if (entry->filename_len == sizeof(".phar/.metadata.bin")-1 && !memcmp(entry->filename, ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1)) {
                entry->phar->metadata = entry->metadata;
-               entry->metadata = NULL;
-       } else if (entry->filename_len >= sizeof(".phar/.metadata/") + sizeof("/.metadata.bin") - 1 && SUCCESS == zend_hash_find(&(entry->phar->manifest), entry->filename + sizeof(".phar/.metadata/") - 1, entry->filename_len - (sizeof("/.metadata.bin") - 1 + sizeof(".phar/.metadata/") - 1), (void *)&mentry)) {
+               ZVAL_UNDEF(&entry->metadata);
+// ??? len ???
+       } else if (entry->filename_len >= sizeof(".phar/.metadata/") + sizeof("/.metadata.bin") - 1 && NULL != (mentry = zend_hash_str_find_ptr(&(entry->phar->manifest), entry->filename + sizeof(".phar/.metadata/") - 1, entry->filename_len - (sizeof("/.metadata.bin") - 1 + sizeof(".phar/.metadata/") - 1)))) {
                /* transfer this metadata to the entry it refers */
                mentry->metadata = entry->metadata;
-               entry->metadata = NULL;
+               ZVAL_UNDEF(&entry->metadata);
        }
 
        efree(metadata);
@@ -467,7 +468,7 @@ bail:
                entry.link = NULL;
 
                if (entry.tar_type == TAR_LINK) {
-                       if (!zend_hash_exists(&myphar->manifest, hdr->linkname, strlen(hdr->linkname))) {
+                       if (!zend_hash_str_exists(&myphar->manifest, hdr->linkname, strlen(hdr->linkname))) {
                                if (error) {
                                        spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%s\"", fname, hdr->linkname);
                                }
@@ -481,7 +482,7 @@ bail:
                        entry.link = estrdup(hdr->linkname);
                }
                phar_set_inode(&entry TSRMLS_CC);
-               zend_hash_add(&myphar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), (void **) &newentry);
+               newentry = zend_hash_str_add_mem(&myphar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info));
 
                if (entry.is_persistent) {
                        ++entry.manifest_pos;
@@ -572,7 +573,7 @@ bail:
                }
        } while (read != 0);
 
-       if (zend_hash_exists(&(myphar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
+       if (zend_hash_str_exists(&(myphar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
                myphar->is_data = 0;
        } else {
                myphar->is_data = 1;
@@ -608,7 +609,7 @@ bail:
 
        phar_request_initialize(TSRMLS_C);
 
-       if (SUCCESS != zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len, (void*)&myphar, sizeof(phar_archive_data*), (void **)&actual)) {
+       if (NULL == (actual = zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len, myphar))) {
                if (error) {
                        spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\" to phar registry", fname);
                }
@@ -620,35 +621,35 @@ bail:
        myphar = *actual;
 
        if (actual_alias) {
-               phar_archive_data **fd_ptr;
+               phar_archive_data *fd_ptr;
 
                myphar->is_temporary_alias = 0;
 
-               if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void **)&fd_ptr)) {
-                       if (SUCCESS != phar_free_alias(*fd_ptr, actual_alias, myphar->alias_len TSRMLS_CC)) {
+               if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len))) {
+                       if (SUCCESS != phar_free_alias(fd_ptr, actual_alias, myphar->alias_len TSRMLS_CC)) {
                                if (error) {
                                        spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname);
                                }
-                               zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len);
+                               zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len);
                                return FAILURE;
                        }
                }
 
-               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
+               zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), actual_alias, myphar->alias_len, myphar);
        } else {
-               phar_archive_data **fd_ptr;
+               phar_archive_data *fd_ptr;
 
                if (alias_len) {
-                       if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
-                               if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+                       if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len))) {
+                               if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len TSRMLS_CC)) {
                                        if (error) {
                                                spprintf(error, 4096, "phar error: Unable to add tar-based phar \"%s\", alias is already in use", fname);
                                        }
-                                       zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len);
+                                       zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len);
                                        return FAILURE;
                                }
                        }
-                       zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&myphar, sizeof(phar_archive_data*), NULL);
+                       zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, myphar);
                        myphar->alias = pestrndup(alias, alias_len, myphar->is_persistent);
                        myphar->alias_len = alias_len;
                } else {
@@ -828,16 +829,15 @@ int phar_tar_setmetadata(zval *metadata, phar_entry_info *entry, char **error TS
 {
        php_serialize_data_t metadata_hash;
 
-       if (entry->metadata_str.c) {
+       if (entry->metadata_str.s) {
                smart_str_free(&entry->metadata_str);
        }
 
-       entry->metadata_str.c = 0;
-       entry->metadata_str.len = 0;
+       entry->metadata_str.s = NULL;
        PHP_VAR_SERIALIZE_INIT(metadata_hash);
-       php_var_serialize(&entry->metadata_str, &metadata, &metadata_hash TSRMLS_CC);
+       php_var_serialize(&entry->metadata_str, metadata, &metadata_hash TSRMLS_CC);
        PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
-       entry->uncompressed_filesize = entry->compressed_filesize = entry->metadata_str.len;
+       entry->uncompressed_filesize = entry->compressed_filesize = entry->metadata_str.s ? entry->metadata_str.s->len : 0;
 
        if (entry->fp && entry->fp_type == PHAR_MOD) {
                php_stream_close(entry->fp);
@@ -851,9 +851,9 @@ int phar_tar_setmetadata(zval *metadata, phar_entry_info *entry, char **error TS
                spprintf(error, 0, "phar error: unable to create temporary file");
                return -1;
        }
-       if (entry->metadata_str.len != php_stream_write(entry->fp, entry->metadata_str.c, entry->metadata_str.len)) {
+       if (entry->metadata_str.s->len != php_stream_write(entry->fp, entry->metadata_str.s->val, entry->metadata_str.s->len)) {
                spprintf(error, 0, "phar tar error: unable to write metadata to magic metadata file \"%s\"", entry->filename);
-               zend_hash_del(&(entry->phar->manifest), entry->filename, entry->filename_len);
+               zend_hash_str_del(&(entry->phar->manifest), entry->filename, entry->filename_len);
                return ZEND_HASH_APPLY_STOP;
        }
 
@@ -870,10 +870,11 @@ static int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{
 
        if (entry->filename_len >= sizeof(".phar/.metadata") && !memcmp(entry->filename, ".phar/.metadata", sizeof(".phar/.metadata")-1)) {
                if (entry->filename_len == sizeof(".phar/.metadata.bin")-1 && !memcmp(entry->filename, ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1)) {
-                       return phar_tar_setmetadata(entry->phar->metadata, entry, error TSRMLS_CC);
+                       return phar_tar_setmetadata(&entry->phar->metadata, entry, error TSRMLS_CC);
                }
                /* search for the file this metadata entry references */
-               if (entry->filename_len >= sizeof(".phar/.metadata/") + sizeof("/.metadata.bin") - 1 && !zend_hash_exists(&(entry->phar->manifest), entry->filename + sizeof(".phar/.metadata/") - 1, entry->filename_len - (sizeof("/.metadata.bin") - 1 + sizeof(".phar/.metadata/") - 1))) {
+//??? len ???
+               if (entry->filename_len >= sizeof(".phar/.metadata/") + sizeof("/.metadata.bin") - 1 && !zend_hash_str_exists(&(entry->phar->manifest), entry->filename + sizeof(".phar/.metadata/") - 1, entry->filename_len - (sizeof("/.metadata.bin") - 1 + sizeof(".phar/.metadata/") - 1))) {
                        /* this is orphaned metadata, erase it */
                        return ZEND_HASH_APPLY_REMOVE;
                }
@@ -888,15 +889,15 @@ static int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{
        /* now we are dealing with regular files, so look for metadata */
        lookfor_len = spprintf(&lookfor, 0, ".phar/.metadata/%s/.metadata.bin", entry->filename);
 
-       if (!entry->metadata) {
-               zend_hash_del(&(entry->phar->manifest), lookfor, lookfor_len);
+       if (Z_TYPE(entry->metadata) == IS_UNDEF) {
+               zend_hash_str_del(&(entry->phar->manifest), lookfor, lookfor_len);
                efree(lookfor);
                return ZEND_HASH_APPLY_KEEP;
        }
 
-       if (SUCCESS == zend_hash_find(&(entry->phar->manifest), lookfor, lookfor_len, (void **)&metadata)) {
+       if (NULL != (metadata = zend_hash_str_find_ptr(&(entry->phar->manifest), lookfor, lookfor_len))) {
                int ret;
-               ret = phar_tar_setmetadata(entry->metadata, metadata, error TSRMLS_CC);
+               ret = phar_tar_setmetadata(&entry->metadata, metadata, error TSRMLS_CC);
                efree(lookfor);
                return ret;
        }
@@ -907,13 +908,13 @@ static int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{
        newentry.tar_type = TAR_FILE;
        newentry.is_tar = 1;
 
-       if (SUCCESS != zend_hash_add(&(entry->phar->manifest), lookfor, lookfor_len, (void *)&newentry, sizeof(phar_entry_info), (void **)&metadata)) {
+       if (NULL == (metadata = zend_hash_str_add_mem(&(entry->phar->manifest), lookfor, lookfor_len, (void *)&newentry, sizeof(phar_entry_info)))) {
                efree(lookfor);
                spprintf(error, 0, "phar tar error: unable to add magic metadata file to manifest for file \"%s\"", entry->filename);
                return ZEND_HASH_APPLY_STOP;
        }
 
-       return phar_tar_setmetadata(entry->metadata, metadata, error TSRMLS_CC);
+       return phar_tar_setmetadata(&entry->metadata, metadata, error TSRMLS_CC);
 }
 /* }}} */
 
@@ -965,14 +966,14 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
 
                entry.uncompressed_filesize = phar->alias_len;
 
-               if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+               if (NULL == zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
                        if (error) {
                                spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
                        }
                        return EOF;
                }
        } else {
-               zend_hash_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
+               zend_hash_str_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
        }
 
        /* set stub */
@@ -980,7 +981,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                char *pos;
                if (len < 0) {
                        /* resource passed in */
-                       if (!(php_stream_from_zval_no_verify(stubfile, (zval **)user_stub))) {
+                       if (!(php_stream_from_zval_no_verify(stubfile, (zval *)user_stub))) {
                                if (error) {
                                        spprintf(error, 0, "unable to access resource to copy stub to new tar-based phar \"%s\"", phar->fname);
                                }
@@ -993,7 +994,21 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                        }
                        user_stub = 0;
 
-                       if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) {
+                       // TODO: refactor to avoid reallocation ???
+//???          len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)
+                       {
+                               zend_string *str = php_stream_copy_to_mem(stubfile, len, 0);
+                               if (str) {
+                                       len = str->len;
+                                       user_stub = estrndup(str->val, str->len);
+                                       STR_RELEASE(str);
+                               } else {
+                                       user_stub = NULL;
+                                       len = 0;
+                               }
+                       }
+
+                       if (!len || !user_stub) {
                                if (error) {
                                        spprintf(error, 0, "unable to read resource to copy stub to new tar-based phar \"%s\"", phar->fname);
                                }
@@ -1040,7 +1055,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
 
                entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
                entry.filename_len = sizeof(".phar/stub.php")-1;
-               zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
+               zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info));
 
                if (free_user_stub) {
                        efree(user_stub);
@@ -1065,8 +1080,8 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                entry.filename_len = sizeof(".phar/stub.php")-1;
 
                if (!defaultstub) {
-                       if (!zend_hash_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
-                               if (SUCCESS != zend_hash_add(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+                       if (!zend_hash_str_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
+                               if (NULL == zend_hash_str_add_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
                                        php_stream_close(entry.fp);
                                        efree(entry.filename);
                                        if (error) {
@@ -1079,7 +1094,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                                efree(entry.filename);
                        }
                } else {
-                       if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+                       if (NULL == zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
                                php_stream_close(entry.fp);
                                efree(entry.filename);
                                if (error) {
@@ -1116,10 +1131,10 @@ nostub:
        pass.free_fp = 1;
        pass.free_ufp = 1;
 
-       if (phar->metadata) {
+       if (Z_TYPE(phar->metadata) != IS_UNDEF) {
                phar_entry_info *mentry;
-               if (SUCCESS == zend_hash_find(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1, (void **)&mentry)) {
-                       if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(phar->metadata, mentry, error TSRMLS_CC)) {
+               if (NULL != (mentry = zend_hash_str_find_ptr(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1))) {
+                       if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(&phar->metadata, mentry, error TSRMLS_CC)) {
                                if (closeoldfile) {
                                        php_stream_close(oldfile);
                                }
@@ -1134,7 +1149,7 @@ nostub:
                        newentry.tar_type = TAR_FILE;
                        newentry.is_tar = 1;
 
-                       if (SUCCESS != zend_hash_add(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1, (void *)&newentry, sizeof(phar_entry_info), (void **)&mentry)) {
+                       if (NULL == (mentry = zend_hash_str_add_mem(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1, (void *)&newentry, sizeof(phar_entry_info)))) {
                                spprintf(error, 0, "phar tar error: unable to add magic metadata file to manifest for phar archive \"%s\"", phar->fname);
                                if (closeoldfile) {
                                        php_stream_close(oldfile);
@@ -1142,8 +1157,8 @@ nostub:
                                return EOF;
                        }
 
-                       if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(phar->metadata, mentry, error TSRMLS_CC)) {
-                               zend_hash_del(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1);
+                       if (ZEND_HASH_APPLY_KEEP != phar_tar_setmetadata(&phar->metadata, mentry, error TSRMLS_CC)) {
+                               zend_hash_str_del(&(phar->manifest), ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1);
                                if (closeoldfile) {
                                        php_stream_close(oldfile);
                                }
index 8aa0cf8ae06eef87fe47152461be72d2ec0b28bd..2cbc0b1716f15db304e79e1e7fbe545a65573776 100644 (file)
@@ -71,8 +71,8 @@ phar_entry_info *phar_get_link_source(phar_entry_info *entry TSRMLS_DC) /* {{{ *
        }
 
        link = phar_get_link_location(entry TSRMLS_CC);
-       if (SUCCESS == zend_hash_find(&(entry->phar->manifest), entry->link, strlen(entry->link), (void **)&link_entry) ||
-               SUCCESS == zend_hash_find(&(entry->phar->manifest), link, strlen(link), (void **)&link_entry)) {
+       if (NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), entry->link, strlen(entry->link))) ||
+               NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), link, strlen(link)))) {
                if (link != entry->link) {
                        efree(link);
                }
@@ -227,7 +227,7 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len,
 
        if (ssb.sb.st_mode & S_IFDIR) {
                entry.is_dir = 1;
-               if (SUCCESS != zend_hash_add(&phar->mounted_dirs, entry.filename, path_len, (void *)&(entry.filename), sizeof(char *), NULL)) {
+               if (NULL != zend_hash_str_add_ptr(&phar->mounted_dirs, entry.filename, path_len, entry.filename)) {
                        /* directory already mounted */
                        efree(entry.tmp);
                        efree(entry.filename);
@@ -240,7 +240,7 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len,
 
        entry.flags = ssb.sb.st_mode;
 
-       if (SUCCESS == zend_hash_add(&phar->manifest, entry.filename, path_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+       if (NULL != zend_hash_str_add_mem(&phar->manifest, entry.filename, path_len, (void*)&entry, sizeof(phar_entry_info))) {
                return SUCCESS;
        }
 
@@ -298,14 +298,14 @@ splitted:
                test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1 TSRMLS_CC);
 
                if (*test == '/') {
-                       if (zend_hash_exists(&(phar->manifest), test + 1, try_len - 1)) {
+                       if (zend_hash_str_exists(&(phar->manifest), test + 1, try_len - 1)) {
                                spprintf(&ret, 0, "phar://%s%s", arch, test);
                                efree(arch);
                                efree(test);
                                return ret;
                        }
                } else {
-                       if (zend_hash_exists(&(phar->manifest), test, try_len)) {
+                       if (zend_hash_str_exists(&(phar->manifest), test, try_len)) {
                                spprintf(&ret, 0, "phar://%s/%s", arch, test);
                                efree(arch);
                                efree(test);
@@ -328,10 +328,10 @@ splitted:
                        return ret;
                }
 
-               zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar);
+               *pphar = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len);
 
-               if (!pphar && PHAR_G(manifest_cached)) {
-                       zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar);
+               if (!*pphar && PHAR_G(manifest_cached)) {
+                       *pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len);
                }
 
                efree(arch);
@@ -592,7 +592,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
                etemp.tar_type = etemp.is_dir ? TAR_DIR : TAR_FILE;
        }
 
-       if (FAILURE == zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), (void **) &entry)) {
+       if (NULL == (entry = zend_hash_str_add_mem(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info)))) {
                php_stream_close(etemp.fp);
                if (error) {
                        spprintf(error, 0, "phar error: unable to add new entry \"%s\" to phar \"%s\"", etemp.filename, phar->fname);
@@ -924,11 +924,11 @@ phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry,
 /* }}} */
 
 PHP_PHAR_API int phar_resolve_alias(char *alias, int alias_len, char **filename, int *filename_len TSRMLS_DC) /* {{{ */ {
-       phar_archive_data **fd_ptr;
+       phar_archive_data *fd_ptr;
        if (PHAR_GLOBALS->phar_alias_map.arHash
-                       && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void**)&fd_ptr)) {
-               *filename = (*fd_ptr)->fname;
-               *filename_len = (*fd_ptr)->fname_len;
+                       && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len))) {
+               *filename = fd_ptr->fname;
+               *filename_len = fd_ptr->fname_len;
                return SUCCESS;
        }
        return FAILURE;
@@ -942,7 +942,7 @@ int phar_free_alias(phar_archive_data *phar, char *alias, int alias_len TSRMLS_D
        }
 
        /* this archive has no open references, so emit an E_STRICT and remove it */
-       if (zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), phar->fname, phar->fname_len) != SUCCESS) {
+       if (zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), phar->fname, phar->fname_len) != SUCCESS) {
                return FAILURE;
        }
 
@@ -960,10 +960,9 @@ int phar_free_alias(phar_archive_data *phar, char *alias, int alias_len TSRMLS_D
  */
 int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, char *alias, int alias_len, char **error TSRMLS_DC) /* {{{ */
 {
-       phar_archive_data *fd, **fd_ptr;
+       phar_archive_data *fd, *fd_ptr;
        char *my_realpath, *save;
        int save_len;
-       ulong fhash, ahash = 0;
 
        phar_request_initialize(TSRMLS_C);
 
@@ -985,11 +984,11 @@ int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, ch
                                return FAILURE;
                        }
 
-                       if (PHAR_G(last_phar)->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len, (void**)&fd_ptr)) {
-                               zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len);
+                       if (PHAR_G(last_phar)->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len))) {
+                               zend_hash_str_del(&(PHAR_GLOBALS->phar_alias_map), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len);
                        }
 
-                       zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void*)&(*archive), sizeof(phar_archive_data*), NULL);
+                       zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, *archive);
                        PHAR_G(last_alias) = alias;
                        PHAR_G(last_alias_len) = alias_len;
                }
@@ -999,19 +998,18 @@ int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, ch
 
        if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) {
                fd = PHAR_G(last_phar);
-               fd_ptr = &fd;
+               fd_ptr = fd;
                goto alias_success;
        }
 
        if (alias && alias_len) {
-               ahash = zend_inline_hash_func(alias, alias_len);
-               if (SUCCESS == zend_hash_quick_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void**)&fd_ptr)) {
+               if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len))) {
 alias_success:
-                       if (fname && (fname_len != (*fd_ptr)->fname_len || strncmp(fname, (*fd_ptr)->fname, fname_len))) {
+                       if (fname && (fname_len != fd_ptr->fname_len || strncmp(fname, fd_ptr->fname, fname_len))) {
                                if (error) {
-                                       spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, (*fd_ptr)->fname, fname);
+                                       spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
                                }
-                               if (SUCCESS == phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+                               if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len TSRMLS_CC)) {
                                        if (error) {
                                                efree(*error);
                                                *error = NULL;
@@ -1020,8 +1018,8 @@ alias_success:
                                return FAILURE;
                        }
 
-                       *archive = *fd_ptr;
-                       fd = *fd_ptr;
+                       *archive = fd_ptr;
+                       fd = fd_ptr;
                        PHAR_G(last_phar) = fd;
                        PHAR_G(last_phar_name) = fd->fname;
                        PHAR_G(last_phar_name_len) = fd->fname_len;
@@ -1031,34 +1029,33 @@ alias_success:
                        return SUCCESS;
                }
 
-               if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_alias, alias, alias_len, ahash, (void **)&fd_ptr)) {
+               if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len))) {
                        goto alias_success;
                }
        }
 
-       fhash = zend_inline_hash_func(fname, fname_len);
        my_realpath = NULL;
        save = fname;
        save_len = fname_len;
 
        if (fname && fname_len) {
-               if (SUCCESS == zend_hash_quick_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, fhash, (void**)&fd_ptr)) {
-                       *archive = *fd_ptr;
-                       fd = *fd_ptr;
+               if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len))) {
+                       *archive = fd_ptr;
+                       fd = fd_ptr;
 
                        if (alias && alias_len) {
                                if (!fd->is_temporary_alias && (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len))) {
                                        if (error) {
-                                               spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, (*fd_ptr)->fname, fname);
+                                               spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
                                        }
                                        return FAILURE;
                                }
 
-                               if (fd->alias_len && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), fd->alias, fd->alias_len, (void**)&fd_ptr)) {
-                                       zend_hash_del(&(PHAR_GLOBALS->phar_alias_map), fd->alias, fd->alias_len);
+                               if (fd->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), fd->alias, fd->alias_len))) {
+                                       zend_hash_str_del(&(PHAR_GLOBALS->phar_alias_map), fd->alias, fd->alias_len);
                                }
 
-                               zend_hash_quick_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void*)&fd, sizeof(phar_archive_data*), NULL);
+                               zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, fd);
                        }
 
                        PHAR_G(last_phar) = fd;
@@ -1070,16 +1067,16 @@ alias_success:
                        return SUCCESS;
                }
 
-               if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_phars, fname, fname_len, fhash, (void**)&fd_ptr)) {
-                       *archive = *fd_ptr;
-                       fd = *fd_ptr;
+               if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
+                       *archive = fd_ptr;
+                       fd = fd_ptr;
 
                        /* this could be problematic - alias should never be different from manifest alias
                           for cached phars */
                        if (!fd->is_temporary_alias && alias && alias_len) {
                                if (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len)) {
                                        if (error) {
-                                               spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, (*fd_ptr)->fname, fname);
+                                               spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
                                        }
                                        return FAILURE;
                                }
@@ -1094,8 +1091,8 @@ alias_success:
                        return SUCCESS;
                }
 
-               if (SUCCESS == zend_hash_quick_find(&(PHAR_GLOBALS->phar_alias_map), save, save_len, fhash, (void**)&fd_ptr)) {
-                       fd = *archive = *fd_ptr;
+               if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), save, save_len))) {
+                       fd = *archive = fd_ptr;
 
                        PHAR_G(last_phar) = fd;
                        PHAR_G(last_phar_name) = fd->fname;
@@ -1106,8 +1103,8 @@ alias_success:
                        return SUCCESS;
                }
 
-               if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_alias, save, save_len, fhash, (void**)&fd_ptr)) {
-                       fd = *archive = *fd_ptr;
+               if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, save, save_len))) {
+                       fd = *archive = fd_ptr;
 
                        PHAR_G(last_phar) = fd;
                        PHAR_G(last_phar_name) = fd->fname;
@@ -1130,15 +1127,14 @@ alias_success:
 #ifdef PHP_WIN32
                phar_unixify_path_separators(fname, fname_len);
 #endif
-               fhash = zend_inline_hash_func(fname, fname_len);
 
-               if (SUCCESS == zend_hash_quick_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, fhash, (void**)&fd_ptr)) {
+               if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len))) {
 realpath_success:
-                       *archive = *fd_ptr;
-                       fd = *fd_ptr;
+                       *archive = fd_ptr;
+                       fd = fd_ptr;
 
                        if (alias && alias_len) {
-                               zend_hash_quick_add(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, ahash, (void*)&fd, sizeof(phar_archive_data*), NULL);
+                               zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, fd);
                        }
 
                        efree(my_realpath);
@@ -1152,7 +1148,7 @@ realpath_success:
                        return SUCCESS;
                }
 
-               if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_quick_find(&cached_phars, fname, fname_len, fhash, (void**)&fd_ptr)) {
+               if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
                        goto realpath_success;
                }
 
@@ -1264,7 +1260,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
                path_len--;
        }
 
-       if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
+       if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
                if (entry->is_deleted) {
                        /* entry is deleted, but has not been flushed to disk yet */
                        return NULL;
@@ -1286,7 +1282,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
        }
 
        if (dir) {
-               if (zend_hash_exists(&phar->virtual_dirs, path, path_len)) {
+               if (zend_hash_str_exists(&phar->virtual_dirs, path, path_len)) {
                        /* a file or directory exists in a sub-directory of this path */
                        entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info));
                        /* this next line tells PharFileInfo->__destruct() to efree the filename */
@@ -1299,38 +1295,31 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
        }
 
        if (phar->mounted_dirs.arHash && zend_hash_num_elements(&phar->mounted_dirs)) {
-               char *str_key;
-               ulong unused;
-               uint keylen;
-
-               zend_hash_internal_pointer_reset(&phar->mounted_dirs);
-               while (FAILURE != zend_hash_has_more_elements(&phar->mounted_dirs)) {
-                       if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&phar->mounted_dirs, &str_key, &keylen, &unused, 0, NULL)) {
-                               break;
-                       }
+               zend_string *str_key;
 
-                       if ((int)keylen >= path_len || strncmp(str_key, path, keylen)) {
+               ZEND_HASH_FOREACH_STR_KEY(&phar->mounted_dirs, str_key) {
+                       if ((int)str_key->len >= path_len || strncmp(str_key->val, path, str_key->len)) {
                                continue;
                        } else {
                                char *test;
                                int test_len;
                                php_stream_statbuf ssb;
 
-                               if (SUCCESS != zend_hash_find(&phar->manifest, str_key, keylen, (void **) &entry)) {
+                               if (NULL == (entry = zend_hash_find_ptr(&phar->manifest, str_key))) {
                                        if (error) {
-                                               spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", str_key);
+                                               spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", str_key->val);
                                        }
                                        return NULL;
                                }
 
                                if (!entry->tmp || !entry->is_mounted) {
                                        if (error) {
-                                               spprintf(error, 4096, "phar internal error: mounted path \"%s\" is not properly initialized as a mounted path", str_key);
+                                               spprintf(error, 4096, "phar internal error: mounted path \"%s\" is not properly initialized as a mounted path", str_key->val);
                                        }
                                        return NULL;
                                }
 
-                               test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, path + keylen);
+                               test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, path + str_key->len);
 
                                if (SUCCESS != php_stream_stat_path(test, &ssb)) {
                                        efree(test);
@@ -1365,7 +1354,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
 
                                efree(test);
 
-                               if (SUCCESS != zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
+                               if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
                                        if (error) {
                                                spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be retrieved after being mounted", path, test);
                                        }
@@ -1373,7 +1362,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
                                }
                                return entry;
                        }
-               }
+               } ZEND_HASH_FOREACH_END();
        }
 
        return NULL;
@@ -1403,109 +1392,77 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end,
 {
        zend_fcall_info fci;
        zend_fcall_info_cache fcc;
-       zval *zdata, *zsig, *zkey, *retval_ptr, **zp[3], *openssl;
-
-       MAKE_STD_ZVAL(zdata);
-       MAKE_STD_ZVAL(openssl);
-       ZVAL_STRINGL(openssl, is_sign ? "openssl_sign" : "openssl_verify", is_sign ? sizeof("openssl_sign")-1 : sizeof("openssl_verify")-1, 1);
-       MAKE_STD_ZVAL(zsig);
-       ZVAL_STRINGL(zsig, *signature, *signature_len, 1);
-       MAKE_STD_ZVAL(zkey);
-       ZVAL_STRINGL(zkey, key, key_len, 1);
-       zp[0] = &zdata;
-       zp[1] = &zsig;
-       zp[2] = &zkey;
-
-       php_stream_rewind(fp);
-       Z_TYPE_P(zdata) = IS_STRING;
-       Z_STRLEN_P(zdata) = end;
-
-       if (end != (off_t) php_stream_copy_to_mem(fp, &(Z_STRVAL_P(zdata)), (size_t) end, 0)) {
-               zval_dtor(zdata);
-               zval_dtor(zsig);
-               zval_dtor(zkey);
-               zval_dtor(openssl);
-               efree(openssl);
-               efree(zdata);
-               efree(zkey);
-               efree(zsig);
+       zval retval, zp[3], openssl;
+
+       ZVAL_STRINGL(&openssl, is_sign ? "openssl_sign" : "openssl_verify", is_sign ? sizeof("openssl_sign")-1 : sizeof("openssl_verify")-1);
+       ZVAL_STRINGL(&zp[1], *signature, *signature_len);
+       ZVAL_STRINGL(&zp[2], key, key_len);
+       ZVAL_STR(&zp[0], php_stream_copy_to_mem(fp, (size_t) end, 0));
+
+       if (end != Z_STRLEN(zp[0])) {
+               zval_dtor(&zp[0]);
+               zval_dtor(&zp[1]);
+               zval_dtor(&zp[2]);
+               zval_dtor(&openssl);
                return FAILURE;
        }
 
-       if (FAILURE == zend_fcall_info_init(openssl, 0, &fci, &fcc, NULL, NULL TSRMLS_CC)) {
-               zval_dtor(zdata);
-               zval_dtor(zsig);
-               zval_dtor(zkey);
-               zval_dtor(openssl);
-               efree(openssl);
-               efree(zdata);
-               efree(zkey);
-               efree(zsig);
+       if (FAILURE == zend_fcall_info_init(&openssl, 0, &fci, &fcc, NULL, NULL TSRMLS_CC)) {
+               zval_dtor(&zp[0]);
+               zval_dtor(&zp[1]);
+               zval_dtor(&zp[2]);
+               zval_dtor(&openssl);
                return FAILURE;
        }
 
        fci.param_count = 3;
        fci.params = zp;
-       Z_ADDREF_P(zdata);
+       Z_ADDREF(zp[0]);
        if (is_sign) {
-               Z_SET_ISREF_P(zsig);
+               ZVAL_NEW_REF(&zp[1], &zp[1]);
        } else {
-               Z_ADDREF_P(zsig);
+               Z_ADDREF(zp[1]);
        }
-       Z_ADDREF_P(zkey);
+       Z_ADDREF(zp[2]);
 
-       fci.retval_ptr_ptr = &retval_ptr;
+       fci.retval = &retval;
 
        if (FAILURE == zend_call_function(&fci, &fcc TSRMLS_CC)) {
-               zval_dtor(zdata);
-               zval_dtor(zsig);
-               zval_dtor(zkey);
-               zval_dtor(openssl);
-               efree(openssl);
-               efree(zdata);
-               efree(zkey);
-               efree(zsig);
+               zval_dtor(&zp[0]);
+               zval_dtor(&zp[1]);
+               zval_dtor(&zp[2]);
+               zval_dtor(&openssl);
                return FAILURE;
        }
 
-       zval_dtor(openssl);
-       efree(openssl);
-       Z_DELREF_P(zdata);
+       zval_dtor(&openssl);
+       Z_DELREF(zp[0]);
 
        if (is_sign) {
-               Z_UNSET_ISREF_P(zsig);
+               ZVAL_UNREF(&zp[1]);
        } else {
-               Z_DELREF_P(zsig);
+               Z_DELREF(zp[1]);
        }
-       Z_DELREF_P(zkey);
+       Z_DELREF(zp[2]);
 
-       zval_dtor(zdata);
-       efree(zdata);
-       zval_dtor(zkey);
-       efree(zkey);
+       zval_dtor(&zp[0]);
+       zval_dtor(&zp[1]);
 
-       switch (Z_TYPE_P(retval_ptr)) {
+       switch (Z_TYPE(retval)) {
                default:
                case IS_LONG:
-                       zval_dtor(zsig);
-                       efree(zsig);
-                       if (1 == Z_LVAL_P(retval_ptr)) {
-                               efree(retval_ptr);
+                       zval_dtor(&zp[1]);
+                       if (1 == Z_LVAL(retval)) {
                                return SUCCESS;
                        }
-                       efree(retval_ptr);
                        return FAILURE;
-               case IS_BOOL:
-                       efree(retval_ptr);
-                       if (Z_BVAL_P(retval_ptr)) {
-                               *signature = estrndup(Z_STRVAL_P(zsig), Z_STRLEN_P(zsig));
-                               *signature_len = Z_STRLEN_P(zsig);
-                               zval_dtor(zsig);
-                               efree(zsig);
-                               return SUCCESS;
-                       }
-                       zval_dtor(zsig);
-                       efree(zsig);
+               case IS_TRUE:
+                       *signature = estrndup(Z_STRVAL(zp[1]), Z_STRLEN(zp[1]));
+                       *signature_len = Z_STRLEN(zp[1]);
+                       zval_dtor(&zp[1]);
+                       return SUCCESS;
+               case IS_FALSE:
+                       zval_dtor(&zp[1]);
                        return FAILURE;
        }
 }
@@ -1530,11 +1487,11 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
 #else
                        int tempsig;
 #endif
-                       php_uint32 pubkey_len;
-                       char *pubkey = NULL, *pfile;
+                       zend_string *pubkey = NULL;
+                       char *pfile;
                        php_stream *pfp;
 #ifndef PHAR_HAVE_OPENSSL
-                       if (!zend_hash_exists(&module_registry, "openssl", sizeof("openssl"))) {
+                       if (!zend_hash_str_exists(&module_registry, "openssl", sizeof("openssl")-1)) {
                                if (error) {
                                        spprintf(error, 0, "openssl not loaded");
                                }
@@ -1546,11 +1503,12 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
                        pfp = php_stream_open_wrapper(pfile, "rb", 0, NULL);
                        efree(pfile);
 
-#if PHP_MAJOR_VERSION > 5
-                       if (!pfp || !(pubkey_len = php_stream_copy_to_mem(pfp, (void **) &pubkey, PHP_STREAM_COPY_ALL, 0)) || !pubkey) {
-#else
-                       if (!pfp || !(pubkey_len = php_stream_copy_to_mem(pfp, &pubkey, PHP_STREAM_COPY_ALL, 0)) || !pubkey) {
-#endif
+//???#if PHP_MAJOR_VERSION > 5
+//???                  if (!pfp || !(pubkey_len = php_stream_copy_to_mem(pfp, (void **) &pubkey, PHP_STREAM_COPY_ALL, 0)) || !pubkey) {
+//???#else
+//???                  if (!pfp || !(pubkey_len = php_stream_copy_to_mem(pfp, &pubkey, PHP_STREAM_COPY_ALL, 0)) || !pubkey) {
+//???#endif
+                       if (!pfp || !(pubkey = php_stream_copy_to_mem(pfp, PHP_STREAM_COPY_ALL, 0)) || !pubkey->len) {
                                if (pfp) {
                                        php_stream_close(pfp);
                                }
@@ -1564,9 +1522,9 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
 #ifndef PHAR_HAVE_OPENSSL
                        tempsig = sig_len;
 
-                       if (FAILURE == phar_call_openssl_signverify(0, fp, end_of_phar, pubkey, pubkey_len, &sig, &tempsig TSRMLS_CC)) {
+                       if (FAILURE == phar_call_openssl_signverify(0, fp, end_of_phar, pubkey ? pubkey->val : NULL, pubkey ? pubkey->len : 0, &sig, &tempsig TSRMLS_CC)) {
                                if (pubkey) {
-                                       efree(pubkey);
+                                       STR_RELEASE(pubkey);
                                }
 
                                if (error) {
@@ -1577,15 +1535,15 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
                        }
 
                        if (pubkey) {
-                               efree(pubkey);
+                               STR_RELEASE(pubkey);
                        }
 
                        sig_len = tempsig;
 #else
-                       in = BIO_new_mem_buf(pubkey, pubkey_len);
+                       in = BIO_new_mem_buf(pubkey ? pubkey->val : NULL, pubkey ? pubkey->len : 0);
 
                        if (NULL == in) {
-                               efree(pubkey);
+                               STR_RELEASE(pubkey);
                                if (error) {
                                        spprintf(error, 0, "openssl signature could not be processed");
                                }
@@ -1594,7 +1552,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
 
                        key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL);
                        BIO_free(in);
-                       efree(pubkey);
+                       STR_RELEASE(pubkey);
 
                        if (NULL == key) {
                                if (error) {
@@ -1965,16 +1923,16 @@ void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int filename
 
        while ((s = zend_memrchr(filename, '/', filename_len))) {
                filename_len = s - filename;
-               if (FAILURE == zend_hash_add_empty_element(&phar->virtual_dirs, filename, filename_len)) {
+               if (NULL == zend_hash_str_add_empty_element(&phar->virtual_dirs, filename, filename_len)) {
                        break;
                }
        }
 }
 /* }}} */
 
-static int phar_update_cached_entry(void *data, void *argument) /* {{{ */
+static int phar_update_cached_entry(zval *data, void *argument) /* {{{ */
 {
-       phar_entry_info *entry = (phar_entry_info *)data;
+       phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(data);
        TSRMLS_FETCH();
 
        entry->phar = (phar_archive_data *)argument;
@@ -1987,26 +1945,19 @@ static int phar_update_cached_entry(void *data, void *argument) /* {{{ */
                entry->tmp = estrdup(entry->tmp);
        }
 
-       entry->metadata_str.c = 0;
+       entry->metadata_str.s = NULL;
        entry->filename = estrndup(entry->filename, entry->filename_len);
        entry->is_persistent = 0;
 
-       if (entry->metadata) {
+       if (Z_TYPE(entry->metadata) != IS_UNDEF) {
                if (entry->metadata_len) {
-                       char *buf = estrndup((char *) entry->metadata, entry->metadata_len);
+                       char *buf = estrndup((char *) Z_PTR(entry->metadata), entry->metadata_len);
                        /* assume success, we would have failed before */
                        phar_parse_metadata((char **) &buf, &entry->metadata, entry->metadata_len TSRMLS_CC);
                        efree(buf);
                } else {
-                       zval *t;
-
-                       t = entry->metadata;
-                       ALLOC_ZVAL(entry->metadata);
-                       *entry->metadata = *t;
-                       zval_copy_ctor(entry->metadata);
-                       Z_SET_REFCOUNT_P(entry->metadata, 1);
-                       entry->metadata_str.c = NULL;
-                       entry->metadata_str.len = 0;
+                       zval_copy_ctor(&entry->metadata);
+                       entry->metadata_str.s = NULL;
                }
        }
        return ZEND_HASH_APPLY_KEEP;
@@ -2018,7 +1969,7 @@ static void phar_copy_cached_phar(phar_archive_data **pphar TSRMLS_DC) /* {{{ */
        phar_archive_data *phar;
        HashTable newmanifest;
        char *fname;
-       phar_archive_object **objphar;
+       phar_archive_object *objphar;
 
        phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data));
        *phar = **pphar;
@@ -2035,66 +1986,58 @@ static void phar_copy_cached_phar(phar_archive_data **pphar TSRMLS_DC) /* {{{ */
                phar->signature = estrdup(phar->signature);
        }
 
-       if (phar->metadata) {
+       if (Z_TYPE(phar->metadata) != IS_UNDEF) {
                /* assume success, we would have failed before */
                if (phar->metadata_len) {
-                       char *buf = estrndup((char *) phar->metadata, phar->metadata_len);
+                       char *buf = estrndup((char *) Z_PTR(phar->metadata), phar->metadata_len);
                        phar_parse_metadata(&buf, &phar->metadata, phar->metadata_len TSRMLS_CC);
                        efree(buf);
                } else {
-                       zval *t;
-
-                       t = phar->metadata;
-                       ALLOC_ZVAL(phar->metadata);
-                       *phar->metadata = *t;
-                       zval_copy_ctor(phar->metadata);
-                       Z_SET_REFCOUNT_P(phar->metadata, 1);
+                       zval_copy_ctor(&phar->metadata);
                }
        }
 
        zend_hash_init(&newmanifest, sizeof(phar_entry_info),
                zend_get_hash_value, destroy_phar_manifest_entry, 0);
-       zend_hash_copy(&newmanifest, &(*pphar)->manifest, NULL, NULL, sizeof(phar_entry_info));
+//???  zend_hash_copy(&newmanifest, &(*pphar)->manifest, NULL, NULL, sizeof(phar_entry_info));
+       zend_hash_copy(&newmanifest, &(*pphar)->manifest, NULL);
        zend_hash_apply_with_argument(&newmanifest, (apply_func_arg_t) phar_update_cached_entry, (void *)phar TSRMLS_CC);
        phar->manifest = newmanifest;
        zend_hash_init(&phar->mounted_dirs, sizeof(char *),
                zend_get_hash_value, NULL, 0);
        zend_hash_init(&phar->virtual_dirs, sizeof(char *),
                zend_get_hash_value, NULL, 0);
-       zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL, NULL, sizeof(void *));
+       zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL);
        *pphar = phar;
 
        /* now, scan the list of persistent Phar objects referencing this phar and update the pointers */
-       for (zend_hash_internal_pointer_reset(&PHAR_GLOBALS->phar_persist_map);
-       SUCCESS == zend_hash_get_current_data(&PHAR_GLOBALS->phar_persist_map, (void **) &objphar);
-       zend_hash_move_forward(&PHAR_GLOBALS->phar_persist_map)) {
-               if (objphar[0]->arc.archive->fname_len == phar->fname_len && !memcmp(objphar[0]->arc.archive->fname, phar->fname, phar->fname_len)) {
-                       objphar[0]->arc.archive = phar;
+       ZEND_HASH_FOREACH_PTR(&PHAR_GLOBALS->phar_persist_map, objphar) {
+               if (objphar->arc.archive->fname_len == phar->fname_len && !memcmp(objphar->arc.archive->fname, phar->fname, phar->fname_len)) {
+                       objphar->arc.archive = phar;
                }
-       }
+       } ZEND_HASH_FOREACH_END();
 }
 /* }}} */
 
 int phar_copy_on_write(phar_archive_data **pphar TSRMLS_DC) /* {{{ */
 {
-       phar_archive_data **newpphar, *newphar = NULL;
+       phar_archive_data *newpphar;
 
-       if (SUCCESS != zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), (*pphar)->fname, (*pphar)->fname_len, (void *)&newphar, sizeof(phar_archive_data *), (void **)&newpphar)) {
+       if (NULL == (newpphar = zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_fname_map), (*pphar)->fname, (*pphar)->fname_len, *pphar))) {
                return FAILURE;
        }
 
-       *newpphar = *pphar;
-       phar_copy_cached_phar(newpphar TSRMLS_CC);
+       phar_copy_cached_phar(&newpphar TSRMLS_CC);
        /* invalidate phar cache */
        PHAR_G(last_phar) = NULL;
        PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
 
-       if (newpphar[0]->alias_len && FAILURE == zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), newpphar[0]->alias, newpphar[0]->alias_len, (void*)newpphar, sizeof(phar_archive_data*), NULL)) {
-               zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), (*pphar)->fname, (*pphar)->fname_len);
+       if (newpphar->alias_len && NULL == zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), newpphar->alias, newpphar->alias_len, newpphar)) {
+               zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), (*pphar)->fname, (*pphar)->fname_len);
                return FAILURE;
        }
 
-       *pphar = *newpphar;
+       *pphar = newpphar;
        return SUCCESS;
 }
 /* }}} */
index 2fc692c33e210f5d0bdb4995abb10cc84bbbbb8f..bbd7126d8aacdf088f3f3c34e6599eb2d233f652 100644 (file)
@@ -241,18 +241,10 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
                                        mydata->metadata_len = 0;
                                        /* if not valid serialized data, it is a regular string */
 
-                                       if (entry.is_persistent) {
-                                               ALLOC_PERMANENT_ZVAL(mydata->metadata);
-                                       } else {
-                                               ALLOC_ZVAL(mydata->metadata);
-                                       }
-
-                                       INIT_ZVAL(*mydata->metadata);
-                                       metadata = pestrndup(metadata, PHAR_GET_16(locator.comment_len), mydata->is_persistent);
-                                       ZVAL_STRINGL(mydata->metadata, metadata, PHAR_GET_16(locator.comment_len), 0);
+                                       ZVAL_STR(&mydata->metadata, STR_INIT(metadata, PHAR_GET_16(locator.comment_len), mydata->is_persistent));
                                }
                        } else {
-                               mydata->metadata = NULL;
+                               ZVAL_UNDEF(&mydata->metadata);
                        }
 
                        goto foundit;
@@ -307,9 +299,7 @@ foundit:
                        zend_hash_destroy(&mydata->virtual_dirs); \
                        mydata->virtual_dirs.arHash = 0; \
                        php_stream_close(fp); \
-                       if (mydata->metadata) { \
-                               zval_dtor(mydata->metadata); \
-                       } \
+                       zval_dtor(&mydata->metadata); \
                        if (mydata->signature) { \
                                efree(mydata->signature); \
                        } \
@@ -331,9 +321,7 @@ foundit:
                        zend_hash_destroy(&mydata->virtual_dirs); \
                        mydata->virtual_dirs.arHash = 0; \
                        php_stream_close(fp); \
-                       if (mydata->metadata) { \
-                               zval_dtor(mydata->metadata); \
-                       } \
+                       zval_dtor(&mydata->metadata); \
                        if (mydata->signature) { \
                                efree(mydata->signature); \
                        } \
@@ -541,17 +529,10 @@ foundit:
                                entry.metadata_len = 0;
                                /* if not valid serialized data, it is a regular string */
 
-                               if (entry.is_persistent) {
-                                       ALLOC_PERMANENT_ZVAL(entry.metadata);
-                               } else {
-                                       ALLOC_ZVAL(entry.metadata);
-                               }
-
-                               INIT_ZVAL(*entry.metadata);
-                               ZVAL_STRINGL(entry.metadata, pestrndup(buf, PHAR_GET_16(zipentry.comment_len), entry.is_persistent), PHAR_GET_16(zipentry.comment_len), 0);
+                               ZVAL_STR(&entry.metadata, STR_INIT(buf, PHAR_GET_16(zipentry.comment_len), entry.is_persistent));
                        }
                } else {
-                       entry.metadata = NULL;
+                       ZVAL_UNDEF(&entry.metadata);
                }
 
                if (!actual_alias && entry.filename_len == sizeof(".phar/alias.txt")-1 && !strncmp(entry.filename, ".phar/alias.txt", sizeof(".phar/alias.txt")-1)) {
@@ -588,7 +569,6 @@ foundit:
                        /* the above lines should be for php < 5.2.6 after 5.3 filters are fixed */
 
                        mydata->alias_len = entry.uncompressed_filesize;
-
                        if (entry.flags & PHAR_ENT_COMPRESSED_GZ) {
                                filter = php_stream_filter_create("zlib.inflate", NULL, php_stream_is_persistent(fp) TSRMLS_CC);
 
@@ -599,7 +579,21 @@ foundit:
 
                                php_stream_filter_append(&fp->readfilters, filter);
 
-                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
+                               // TODO: refactor to avoid reallocation ???
+//???                  entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
+                               {
+                                       zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
+                                       if (str) {
+                                               entry.uncompressed_filesize = str->len;
+                                               actual_alias = estrndup(str->val, str->len);
+                                               STR_RELEASE(str);
+                                       } else {
+                                               actual_alias = NULL;
+                                               entry.uncompressed_filesize = 0;
+                                       }
+                               }
+
+                               if (!entry.uncompressed_filesize || !actual_alias) {
                                        pefree(entry.filename, entry.is_persistent);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
@@ -617,7 +611,21 @@ foundit:
 
                                php_stream_filter_append(&fp->readfilters, filter);
 
-                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
+                               // TODO: refactor to avoid reallocation ???
+//???                  entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
+                               {
+                                       zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
+                                       if (str) {
+                                               entry.uncompressed_filesize = str->len;
+                                               actual_alias = estrndup(str->val, str->len);
+                                               STR_RELEASE(str);
+                                       } else {
+                                               actual_alias = NULL;
+                                               entry.uncompressed_filesize = 0;
+                                       }
+                               }
+
+                               if (!entry.uncompressed_filesize || !actual_alias) {
                                        pefree(entry.filename, entry.is_persistent);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
@@ -625,7 +633,21 @@ foundit:
                                php_stream_filter_flush(filter, 1);
                                php_stream_filter_remove(filter, 1 TSRMLS_CC);
                        } else {
-                               if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
+                               // TODO: refactor to avoid reallocation ???
+//???                  entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)
+                               {
+                                       zend_string *str = php_stream_copy_to_mem(fp, entry.uncompressed_filesize, 0);
+                                       if (str) {
+                                               entry.uncompressed_filesize = str->len;
+                                               actual_alias = estrndup(str->val, str->len);
+                                               STR_RELEASE(str);
+                                       } else {
+                                               actual_alias = NULL;
+                                               entry.uncompressed_filesize = 0;
+                                       }
+                               }
+
+                               if (!entry.uncompressed_filesize || !actual_alias) {
                                        pefree(entry.filename, entry.is_persistent);
                                        PHAR_ZIP_FAIL("unable to read in alias, truncated");
                                }
@@ -636,40 +658,40 @@ foundit:
                }
 
                phar_set_inode(&entry TSRMLS_CC);
-               zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry,sizeof(phar_entry_info), NULL);
+               zend_hash_str_add_mem(&mydata->manifest, entry.filename, entry.filename_len, (void *)&entry, sizeof(phar_entry_info));
        }
 
        mydata->fp = fp;
 
-       if (zend_hash_exists(&(mydata->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
+       if (zend_hash_str_exists(&(mydata->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
                mydata->is_data = 0;
        } else {
                mydata->is_data = 1;
        }
 
-       zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+       zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, mydata);
 
        if (actual_alias) {
-               phar_archive_data **fd_ptr;
+               phar_archive_data *fd_ptr;
 
                if (!phar_validate_alias(actual_alias, mydata->alias_len)) {
                        if (error) {
                                spprintf(error, 4096, "phar error: invalid alias \"%s\" in zip-based phar \"%s\"", actual_alias, fname);
                        }
                        efree(actual_alias);
-                       zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                       zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
                        return FAILURE;
                }
 
                mydata->is_temporary_alias = 0;
 
-               if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void **)&fd_ptr)) {
-                       if (SUCCESS != phar_free_alias(*fd_ptr, actual_alias, mydata->alias_len TSRMLS_CC)) {
+               if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len))) {
+                       if (SUCCESS != phar_free_alias(fd_ptr, actual_alias, mydata->alias_len TSRMLS_CC)) {
                                if (error) {
                                        spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with implicit alias, alias is already in use", fname);
                                }
                                efree(actual_alias);
-                               zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                               zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
                                return FAILURE;
                        }
                }
@@ -680,22 +702,22 @@ foundit:
                        efree(actual_alias);
                }
 
-               zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+               zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, mydata);
        } else {
-               phar_archive_data **fd_ptr;
+               phar_archive_data *fd_ptr;
 
                if (alias_len) {
-                       if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void **)&fd_ptr)) {
-                               if (SUCCESS != phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) {
+                       if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len))) {
+                               if (SUCCESS != phar_free_alias(fd_ptr, alias, alias_len TSRMLS_CC)) {
                                        if (error) {
                                                spprintf(error, 4096, "phar error: Unable to add zip-based phar \"%s\" with explicit alias, alias is already in use", fname);
                                        }
-                                       zend_hash_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
+                                       zend_hash_str_del(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len);
                                        return FAILURE;
                                }
                        }
 
-                       zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
+                       zend_hash_str_add_ptr(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, mydata);
                        mydata->alias = pestrndup(alias, alias_len, mydata->is_persistent);
                        mydata->alias_len = alias_len;
                } else {
@@ -761,7 +783,7 @@ struct _phar_zip_pass {
        char **error;
 };
 /* perform final modification of zip contents for each file in the manifest before saving */
-static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
+static int phar_zip_changed_apply(zval *zv, void *arg TSRMLS_DC) /* {{{ */
 {
        phar_entry_info *entry;
        phar_zip_file_header local;
@@ -771,7 +793,7 @@ static int phar_zip_changed_apply(void *data, void *arg TSRMLS_DC) /* {{{ */
        php_uint32 newcrc32;
        off_t offset;
        int not_really_modified = 0;
-       entry = (phar_entry_info *)data;
+       entry = (phar_entry_info *)Z_PTR_P(zv);
        p = (struct _phar_zip_pass*) arg;
 
        if (entry->is_mounted) {
@@ -939,18 +961,17 @@ not_compressed:
        PHAR_SET_32(local.crc32, entry->crc32);
 continue_dir:
        /* set file metadata */
-       if (entry->metadata) {
+       if (Z_TYPE(entry->metadata) != IS_UNDEF) {
                php_serialize_data_t metadata_hash;
 
-               if (entry->metadata_str.c) {
+               if (entry->metadata_str.s) {
                        smart_str_free(&entry->metadata_str);
                }
-               entry->metadata_str.c = 0;
-               entry->metadata_str.len = 0;
+               entry->metadata_str.s = NULL;
                PHP_VAR_SERIALIZE_INIT(metadata_hash);
                php_var_serialize(&entry->metadata_str, &entry->metadata, &metadata_hash TSRMLS_CC);
                PHP_VAR_SERIALIZE_DESTROY(metadata_hash);
-               PHAR_SET_16(central.comment_len, entry->metadata_str.len);
+               PHAR_SET_16(central.comment_len, entry->metadata_str.s->len);
        }
 
        entry->header_offset = php_stream_tell(p->filefp);
@@ -1060,8 +1081,8 @@ continue_dir:
        entry->offset = entry->offset_abs = offset;
        entry->fp_type = PHAR_FP;
 
-       if (entry->metadata_str.c) {
-               if (entry->metadata_str.len != php_stream_write(p->centralfp, entry->metadata_str.c, entry->metadata_str.len)) {
+       if (entry->metadata_str.s) {
+               if (entry->metadata_str.s->len != php_stream_write(p->centralfp, entry->metadata_str.s->val, entry->metadata_str.s->len)) {
                        spprintf(p->error, 0, "unable to write metadata as file comment for file \"%s\" while creating zip-based phar \"%s\"", entry->filename, entry->phar->fname);
                        smart_str_free(&entry->metadata_str);
                        return ZEND_HASH_APPLY_STOP;
@@ -1097,8 +1118,8 @@ static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pas
                tell = php_stream_tell(pass->centralfp);
                php_stream_seek(pass->centralfp, 0, SEEK_SET);
                php_stream_copy_to_stream_ex(pass->centralfp, newfile, tell, NULL);
-               if (metadata->c) {
-                       php_stream_write(newfile, metadata->c, metadata->len);
+               if (metadata->s) {
+                       php_stream_write(newfile, metadata->s->val, metadata->s->len);
                }
 
                if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, pass->error TSRMLS_CC)) {
@@ -1206,14 +1227,14 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
                entry.filename_len = sizeof(".phar/alias.txt")-1;
 
-               if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+               if (NULL == zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
                        if (error) {
                                spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
                        }
                        return EOF;
                }
        } else {
-               zend_hash_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
+               zend_hash_str_del(&phar->manifest, ".phar/alias.txt", sizeof(".phar/alias.txt")-1);
        }
 
        /* register alias */
@@ -1227,7 +1248,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
        if (user_stub && !defaultstub) {
                if (len < 0) {
                        /* resource passed in */
-                       if (!(php_stream_from_zval_no_verify(stubfile, (zval **)user_stub))) {
+                       if (!(php_stream_from_zval_no_verify(stubfile, (zval *)user_stub))) {
                                if (error) {
                                        spprintf(error, 0, "unable to access resource to copy stub to new zip-based phar \"%s\"", phar->fname);
                                }
@@ -1242,7 +1263,21 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
 
                        user_stub = 0;
 
-                       if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) {
+                       // TODO: refactor to avoid reallocation ???
+//???          len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)
+                       {
+                               zend_string *str = php_stream_copy_to_mem(stubfile, len, 0);
+                               if (str) {
+                                       len = str->len;
+                                       user_stub = estrndup(str->val, str->len);
+                                       STR_RELEASE(str);
+                               } else {
+                                       user_stub = NULL;
+                                       len = 0;
+                               }
+                       }
+
+                       if (!len || !user_stub) {
                                if (error) {
                                        spprintf(error, 0, "unable to read resource to copy stub to new zip-based phar \"%s\"", phar->fname);
                                }
@@ -1290,7 +1325,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
                entry.filename_len = sizeof(".phar/stub.php")-1;
 
-               if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+               if (NULL == zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
                        if (free_user_stub) {
                                efree(user_stub);
                        }
@@ -1323,8 +1358,8 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                entry.filename_len = sizeof(".phar/stub.php")-1;
 
                if (!defaultstub) {
-                       if (!zend_hash_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
-                               if (SUCCESS != zend_hash_add(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+                       if (!zend_hash_str_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
+                               if (NULL == zend_hash_str_add_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
                                        php_stream_close(entry.fp);
                                        efree(entry.filename);
                                        if (error) {
@@ -1337,7 +1372,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                                efree(entry.filename);
                        }
                } else {
-                       if (SUCCESS != zend_hash_update(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {
+                       if (NULL == zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
                                php_stream_close(entry.fp);
                                efree(entry.filename);
                                if (error) {
@@ -1394,7 +1429,7 @@ fperror:
        }
        zend_hash_apply_with_argument(&phar->manifest, phar_zip_changed_apply, (void *) &pass TSRMLS_CC);
 
-       if (phar->metadata) {
+       if (Z_TYPE(phar->metadata) != IS_UNDEF) {
                /* set phar metadata */
                PHP_VAR_SERIALIZE_INIT(metadata_hash);
                php_var_serialize(&main_metadata_str, &phar->metadata, &metadata_hash TSRMLS_CC);
@@ -1408,7 +1443,7 @@ fperror:
 temperror:
                php_stream_close(pass.centralfp);
 nocentralerror:
-               if (phar->metadata) {
+               if (Z_TYPE(phar->metadata) != IS_UNDEF) {
                        smart_str_free(&main_metadata_str);
                }
                php_stream_close(pass.filefp);
@@ -1442,9 +1477,9 @@ nocentralerror:
 
        php_stream_close(pass.centralfp);
 
-       if (phar->metadata) {
+       if (Z_TYPE(phar->metadata) != IS_UNDEF) {
                /* set phar metadata */
-               PHAR_SET_16(eocd.comment_len, main_metadata_str.len);
+               PHAR_SET_16(eocd.comment_len, main_metadata_str.s->len);
 
                if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) {
                        if (error) {
@@ -1453,7 +1488,7 @@ nocentralerror:
                        goto nocentralerror;
                }
 
-               if (main_metadata_str.len != php_stream_write(pass.filefp, main_metadata_str.c, main_metadata_str.len)) {
+               if (main_metadata_str.s->len != php_stream_write(pass.filefp, main_metadata_str.s->val, main_metadata_str.s->len)) {
                        if (error) {
                                spprintf(error, 4096, "phar zip flush of \"%s\" failed: unable to write metadata to zip comment", phar->fname);
                        }