diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 430f4dec02e2..d2b382390009 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -71,33 +71,49 @@ END_EXTERN_C() /*---*/ -#define ZSTR_IS_INTERNED(s) (GC_FLAGS(s) & IS_STR_INTERNED) -#define ZSTR_IS_VALID_UTF8(s) (GC_FLAGS(s) & IS_STR_VALID_UTF8) +static zend_always_inline bool ZSTR_IS_INTERNED(const zend_string *s) { + return GC_FLAGS(s) & IS_STR_INTERNED; +} + +static inline bool ZSTR_IS_VALID_UTF8(const zend_string *s) { + return GC_FLAGS(s) & IS_STR_VALID_UTF8; +} /* These are properties, encoded as flags, that will hold on the resulting string * after concatenating two strings that have these property. * Example: concatenating two UTF-8 strings yields another UTF-8 string. */ #define ZSTR_COPYABLE_CONCAT_PROPERTIES (IS_STR_VALID_UTF8) -#define ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s) (GC_FLAGS(s) & ZSTR_COPYABLE_CONCAT_PROPERTIES) -/* This macro returns the copyable concat properties which hold on both strings. */ -#define ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(s1, s2) (GC_FLAGS(s1) & GC_FLAGS(s2) & ZSTR_COPYABLE_CONCAT_PROPERTIES) +static inline uint32_t ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(const zend_string *s) { + return GC_FLAGS(s) & ZSTR_COPYABLE_CONCAT_PROPERTIES; +} -#define ZSTR_COPY_CONCAT_PROPERTIES(out, in) do { \ - zend_string *_out = (out); \ - uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES((in)); \ - GC_ADD_FLAGS(_out, properties); \ -} while (0) +/* This function returns the copyable concat properties which hold on both strings. */ +static inline uint32_t ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(const zend_string *s1, const zend_string *s2) { + return ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s1) & ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(s2); +} -#define ZSTR_COPY_CONCAT_PROPERTIES_BOTH(out, in1, in2) do { \ - zend_string *_out = (out); \ - uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH((in1), (in2)); \ - GC_ADD_FLAGS(_out, properties); \ -} while (0) +static inline void ZSTR_COPY_CONCAT_PROPERTIES(zend_string *out, const zend_string *in) { + uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(in); + GC_ADD_FLAGS(out, properties); +} -#define ZSTR_EMPTY_ALLOC() zend_empty_string -#define ZSTR_CHAR(c) zend_one_char_string[c] -#define ZSTR_KNOWN(idx) zend_known_strings[idx] +static inline void ZSTR_COPY_CONCAT_PROPERTIES_BOTH(zend_string *out, const zend_string *in1, const zend_string *in2) { + uint32_t properties = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(in1, in2); + GC_ADD_FLAGS(out, properties); +} + +static zend_always_inline zend_string *ZSTR_EMPTY_ALLOC(void) { + return zend_empty_string; +} + +static zend_always_inline zend_string *ZSTR_CHAR(unsigned char c) { + return zend_one_char_string[c]; +} + +static zend_always_inline zend_string *ZSTR_KNOWN(size_t idx) { + return zend_known_strings[idx]; +} #define _ZSTR_HEADER_SIZE XtOffsetOf(zend_string, val) diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index bdd90851fecc..4bef14dfe6ae 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -287,10 +287,6 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path, return NULL; } - if (error) { - efree(error); - } - if (zend_string_equals(resource->path, ZSTR_CHAR('/'))) { /* root directory requested */ php_url_free(resource); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index c07ff93b951f..bc55c175f7ba 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1655,9 +1655,6 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ return ZEND_HASH_APPLY_STOP; } else { - if (error) { - efree(error); - } /* convert to PHAR_UFP */ if (data->internal_file->fp_type == PHAR_MOD) { php_stream_close(data->internal_file->fp); @@ -3603,10 +3600,6 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con } goto finish; } else { - if (error) { - efree(error); - } - if (!data->internal_file->is_dir) { size_t contents_len = 0; if (content) { @@ -3683,10 +3676,6 @@ static void phar_mkdir(phar_archive_data **pphar, zend_string *dir_name) return; } else { - if (error) { - efree(error); - } - /* check for copy on write */ if (data->phar != *pphar) { *pphar = data->phar; diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 1d9229c44621..f49bc5e2deba 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -200,9 +200,6 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, const cha php_url_free(resource); return NULL; } - if (error) { - efree(error); - } fpf = php_stream_alloc(&phar_ops, idata, NULL, mode); php_url_free(resource); efree(internal_file); @@ -706,9 +703,6 @@ static int phar_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int php_url_free(resource); return 0; } - if (error) { - efree(error); - } if (idata->internal_file->fp_refcount > 1) { /* more than just our fp resource is open for this file */ php_stream_wrapper_log_error(wrapper, options, "phar error: \"%s\" in phar \"%s\", has open file pointers, cannot unlink", internal_file, ZSTR_VAL(resource->host)); diff --git a/ext/phar/util.c b/ext/phar/util.c index efab7f9edab6..491a07c4dd21 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -962,8 +962,7 @@ zend_result phar_free_alias(const phar_archive_data *phar) /* {{{ */ */ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error) /* {{{ */ { - phar_archive_data *fd, *fd_ptr; - char *my_realpath; + phar_archive_data *fd_ptr; phar_request_initialize(); @@ -985,7 +984,7 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz return FAILURE; } - if (PHAR_G(last_phar)->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len))) { + if (PHAR_G(last_phar)->alias_len && zend_hash_str_exists(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len)) { zend_hash_str_del(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len); } @@ -997,16 +996,20 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz return SUCCESS; } - 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; - goto alias_success; - } - if (alias && alias_len) { - fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len); + /* If the alias stored in the last_phar cache matches, just use it directly */ + if (PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) { + fd_ptr = PHAR_G(last_phar); + } else { + fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len); + } + + /* If we didn't find the alias, check in the cached manifest to see if we can find it */ + if (!fd_ptr && PHAR_G(manifest_cached)) { + fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len); + } + if (fd_ptr) { -alias_success: if (!zend_string_equals_cstr(fd_ptr->fname, fname, fname_len)) { if (error) { spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(fd_ptr->fname), fname); @@ -1021,61 +1024,50 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz } *archive = fd_ptr; - fd = fd_ptr; - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; + PHAR_G(last_phar) = fd_ptr; + PHAR_G(last_phar_name) = fd_ptr->fname; PHAR_G(last_alias) = alias; PHAR_G(last_alias_len) = alias_len; return SUCCESS; } - - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len))) { - goto alias_success; - } } - my_realpath = NULL; - const char *save = fname; - size_t save_len = fname_len; - if (fname && fname_len) { fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len); if (fd_ptr) { *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 (!fd_ptr->is_temporary_alias && (alias_len != fd_ptr->alias_len || memcmp(fd_ptr->alias, alias, alias_len))) { if (error) { spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(fd_ptr->fname), fname); } return FAILURE; } - if (fd->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len))) { - zend_hash_str_del(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len); + if (fd_ptr->alias_len && zend_hash_str_exists(&(PHAR_G(phar_alias_map)), fd_ptr->alias, fd_ptr->alias_len)) { + zend_hash_str_del(&(PHAR_G(phar_alias_map)), fd_ptr->alias, fd_ptr->alias_len); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd_ptr); } - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = fd_ptr; + PHAR_G(last_phar_name) = fd_ptr->fname; + PHAR_G(last_alias) = fd_ptr->alias; + PHAR_G(last_alias_len) = fd_ptr->alias_len; return SUCCESS; } 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 (!fd_ptr->is_temporary_alias && alias && alias_len) { + if (alias_len != fd_ptr->alias_len || memcmp(fd_ptr->alias, alias, alias_len)) { if (error) { spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, ZSTR_VAL(fd_ptr->fname), fname); } @@ -1083,76 +1075,66 @@ zend_result phar_get_archive(phar_archive_data **archive, const char *fname, siz } } - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = fd_ptr; + PHAR_G(last_phar_name) = fd_ptr->fname; + PHAR_G(last_alias) = fd_ptr->alias; + PHAR_G(last_alias_len) = fd_ptr->alias_len; return SUCCESS; } - fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), save, save_len); - if (fd_ptr) { - fd = *archive = fd_ptr; - - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fname, fname_len); - return SUCCESS; + /* If we didn't find the fname in the alias map, check in the cached manifest to see if we can find it */ + if (!fd_ptr && PHAR_G(manifest_cached)) { + fd_ptr = zend_hash_str_find_ptr(&cached_alias, fname, fname_len); } - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, save, save_len))) { - fd = *archive = fd_ptr; + if (fd_ptr) { + *archive = fd_ptr; - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = fd_ptr; + PHAR_G(last_phar_name) = fd_ptr->fname; + PHAR_G(last_alias) = fd_ptr->alias; + PHAR_G(last_alias_len) = fd_ptr->alias_len; return SUCCESS; } /* not found, try converting \ to / */ - my_realpath = expand_filepath(fname, my_realpath); + char *my_realpath = expand_filepath(fname, NULL); - if (my_realpath) { - size_t my_realpath_len = strlen(my_realpath); + if (UNEXPECTED(!my_realpath)) { + return FAILURE; + } + + size_t my_realpath_len = strlen(my_realpath); #ifdef PHP_WIN32 - phar_unixify_path_separators(my_realpath, my_realpath_len); + phar_unixify_path_separators(my_realpath, my_realpath_len); #endif - fname_len = my_realpath_len; - fname = my_realpath; - } else { - return FAILURE; + + fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), my_realpath, my_realpath_len); + + /* If we didn't find the path in the fname map, check in the cached manifest to see if we can find it */ + if (!fd_ptr && PHAR_G(manifest_cached)) { + fd_ptr = zend_hash_str_find_ptr(&cached_phars, my_realpath, my_realpath_len); } + efree(my_realpath); - fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len); if (fd_ptr) { -realpath_success: *archive = fd_ptr; - fd = fd_ptr; if (alias && alias_len) { - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd_ptr); } - efree(my_realpath); - - PHAR_G(last_phar) = fd; - PHAR_G(last_phar_name) = fd->fname; - PHAR_G(last_alias) = fd->alias; - PHAR_G(last_alias_len) = fd->alias_len; + PHAR_G(last_phar) = fd_ptr; + PHAR_G(last_phar_name) = fd_ptr->fname; + PHAR_G(last_alias) = fd_ptr->alias; + PHAR_G(last_alias_len) = fd_ptr->alias_len; return SUCCESS; } - - if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) { - goto realpath_success; - } - - efree(my_realpath); } return FAILURE;