diff options
Diffstat (limited to 'ext/zip/php_zip.c')
-rw-r--r-- | ext/zip/php_zip.c | 113 |
1 files changed, 58 insertions, 55 deletions
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index d83272f564..4fedabad1c 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -137,18 +137,18 @@ static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */ # define CWD_STATE_FREE(s) efree(s) /* {{{ php_zip_extract_file */ -static int php_zip_extract_file(struct zip * za, char *dest, char *file, int file_len) +static int php_zip_extract_file(struct zip * za, char *dest, char *file, size_t file_len) { php_stream_statbuf ssb; struct zip_file *zf; struct zip_stat sb; char b[8192]; - int n, len, ret; + int n, ret; php_stream *stream; char *fullpath; char *file_dirname_fullpath; char file_dirname[MAXPATHLEN]; - size_t dir_len; + size_t dir_len, len; int is_dir_only = 0; char *path_cleaned; size_t path_cleaned_len; @@ -181,7 +181,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil memcpy(file_dirname, path_cleaned, path_cleaned_len); dir_len = php_dirname(file_dirname, path_cleaned_len); - if (dir_len <= 0 || (dir_len == 1 && file_dirname[0] == '.')) { + if (!dir_len || (dir_len == 1 && file_dirname[0] == '.')) { len = spprintf(&file_dirname_fullpath, 0, "%s", dest); } else { len = spprintf(&file_dirname_fullpath, 0, "%s/%s", dest, file_dirname); @@ -191,7 +191,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) { efree(file_dirname_fullpath); - zend_string_release(file_basename); + zend_string_release_ex(file_basename, 0); CWD_STATE_FREE(new_state.cwd); return 0; } @@ -203,7 +203,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil if (!ret) { efree(file_dirname_fullpath); if (!is_dir_only) { - zend_string_release(file_basename); + zend_string_release_ex(file_basename, 0); CWD_STATE_FREE(new_state.cwd); } return 0; @@ -220,13 +220,13 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil len = spprintf(&fullpath, 0, "%s/%s", file_dirname_fullpath, ZSTR_VAL(file_basename)); if (!len) { efree(file_dirname_fullpath); - zend_string_release(file_basename); + zend_string_release_ex(file_basename, 0); CWD_STATE_FREE(new_state.cwd); return 0; } else if (len > MAXPATHLEN) { php_error_docref(NULL, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN); efree(file_dirname_fullpath); - zend_string_release(file_basename); + zend_string_release_ex(file_basename, 0); CWD_STATE_FREE(new_state.cwd); return 0; } @@ -238,7 +238,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil if (ZIP_OPENBASEDIR_CHECKPATH(fullpath)) { efree(fullpath); efree(file_dirname_fullpath); - zend_string_release(file_basename); + zend_string_release_ex(file_basename, 0); CWD_STATE_FREE(new_state.cwd); return 0; } @@ -268,7 +268,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil done: efree(fullpath); - zend_string_release(file_basename); + zend_string_release_ex(file_basename, 0); efree(file_dirname_fullpath); CWD_STATE_FREE(new_state.cwd); @@ -625,6 +625,7 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val #endif int files_cnt; zend_string **namelist; + pcre2_match_context *mctx = php_pcre_mctx(); #ifdef ZTS if (!IS_ABSOLUTE_PATH(path, path_len)) { @@ -651,11 +652,12 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val files_cnt = php_stream_scandir(path, &namelist, NULL, (void *) php_stream_dirent_alphasort); if (files_cnt > 0) { - pcre *re = NULL; - pcre_extra *pcre_extra = NULL; - int preg_options = 0, i; + pcre2_code *re = NULL; + pcre2_match_data *match_data = NULL; + uint32_t preg_options = 0, i, capture_count; + int rc; - re = pcre_get_compiled_regex(regexp, &pcre_extra, &preg_options); + re = pcre_get_compiled_regex(regexp, &capture_count, &preg_options); if (!re) { php_error_docref(NULL, E_WARNING, "Invalid expression"); return -1; @@ -667,20 +669,18 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val for (i = 0; i < files_cnt; i++) { zend_stat_t s; char fullpath[MAXPATHLEN]; - int ovector[3]; - int matches; - int namelist_len = ZSTR_LEN(namelist[i]); + size_t namelist_len = ZSTR_LEN(namelist[i]); if ((namelist_len == 1 && ZSTR_VAL(namelist[i])[0] == '.') || (namelist_len == 2 && ZSTR_VAL(namelist[i])[0] == '.' && ZSTR_VAL(namelist[i])[1] == '.')) { - zend_string_release(namelist[i]); + zend_string_release_ex(namelist[i], 0); continue; } if ((path_len + namelist_len + 1) >= MAXPATHLEN) { - php_error_docref(NULL, E_WARNING, "add_path string too long (max: %i, %i given)", + php_error_docref(NULL, E_WARNING, "add_path string too long (max: %u, %zu given)", MAXPATHLEN - 1, (path_len + namelist_len + 1)); - zend_string_release(namelist[i]); + zend_string_release_ex(namelist[i], 0); break; } @@ -688,24 +688,31 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val if (0 != VCWD_STAT(fullpath, &s)) { php_error_docref(NULL, E_WARNING, "Cannot read <%s>", fullpath); - zend_string_release(namelist[i]); + zend_string_release_ex(namelist[i], 0); continue; } if (S_IFDIR == (s.st_mode & S_IFMT)) { - zend_string_release(namelist[i]); + zend_string_release_ex(namelist[i], 0); continue; } - matches = pcre_exec(re, NULL, ZSTR_VAL(namelist[i]), ZSTR_LEN(namelist[i]), 0, 0, ovector, 3); + match_data = php_pcre_create_match_data(capture_count, re); + if (!match_data) { + /* Allocation failed, but can proceed to the next pattern. */ + zend_string_release_ex(namelist[i], 0); + continue; + } + rc = pcre2_match(re, (PCRE2_SPTR)ZSTR_VAL(namelist[i]), ZSTR_LEN(namelist[i]), 0, preg_options, match_data, mctx); + php_pcre_free_match_data(match_data); /* 0 means that the vector is too small to hold all the captured substring offsets */ - if (matches < 0) { - zend_string_release(namelist[i]); + if (rc < 0) { + zend_string_release_ex(namelist[i], 0); continue; } add_next_index_string(return_value, fullpath); - zend_string_release(namelist[i]); + zend_string_release_ex(namelist[i], 0); } efree(namelist); } @@ -800,15 +807,20 @@ typedef struct _zip_prop_handler { static void php_zip_register_prop_handler(HashTable *prop_handler, char *name, zip_read_int_t read_int_func, zip_read_const_char_t read_char_func, zip_read_const_char_from_ze_t read_char_from_obj_func, int rettype) /* {{{ */ { zip_prop_handler hnd; + zend_string *str; + zval tmp; hnd.read_const_char_func = read_char_func; hnd.read_int_func = read_int_func; hnd.read_const_char_from_obj_func = read_char_from_obj_func; hnd.type = rettype; - zend_hash_str_add_mem(prop_handler, name, strlen(name), &hnd, sizeof(zip_prop_handler)); + str = zend_string_init_interned(name, strlen(name), 1); + zend_hash_add_mem(prop_handler, str, &hnd, sizeof(zip_prop_handler)); /* Register for reflection */ - zend_declare_property_null(zip_class_entry, name, strlen(name), ZEND_ACC_PUBLIC); + ZVAL_NULL(&tmp); + zend_declare_property_ex(zip_class_entry, str, &tmp, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(str, 1); } /* }}} */ @@ -866,11 +878,9 @@ static zval *php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, zval tmp_member; zval *retval = NULL; zip_prop_handler *hnd = NULL; - zend_object_handlers *std_hnd; if (Z_TYPE_P(member) != IS_STRING) { - ZVAL_COPY(&tmp_member, member); - convert_to_string(&tmp_member); + ZVAL_STR(&tmp_member, zval_get_string_func(member)); member = &tmp_member; cache_slot = NULL; } @@ -882,12 +892,11 @@ static zval *php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, } if (hnd == NULL) { - std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->get_property_ptr_ptr(object, member, type, cache_slot); + retval = zend_std_get_property_ptr_ptr(object, member, type, cache_slot); } if (member == &tmp_member) { - zval_dtor(member); + zval_ptr_dtor_str(&tmp_member); } return retval; @@ -900,11 +909,9 @@ static zval *php_zip_read_property(zval *object, zval *member, int type, void ** zval tmp_member; zval *retval = NULL; zip_prop_handler *hnd = NULL; - zend_object_handlers *std_hnd; if (Z_TYPE_P(member) != IS_STRING) { - ZVAL_COPY(&tmp_member, member); - convert_to_string(&tmp_member); + ZVAL_STR(&tmp_member, zval_get_string_func(member)); member = &tmp_member; cache_slot = NULL; } @@ -921,12 +928,11 @@ static zval *php_zip_read_property(zval *object, zval *member, int type, void ** retval = &EG(uninitialized_zval); } } else { - std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->read_property(object, member, type, cache_slot, rv); + retval = zend_std_read_property(object, member, type, cache_slot, rv); } if (member == &tmp_member) { - zval_dtor(member); + zval_ptr_dtor_str(&tmp_member); } return retval; @@ -938,12 +944,10 @@ static int php_zip_has_property(zval *object, zval *member, int type, void **cac ze_zip_object *obj; zval tmp_member; zip_prop_handler *hnd = NULL; - zend_object_handlers *std_hnd; int retval = 0; if (Z_TYPE_P(member) != IS_STRING) { - ZVAL_COPY(&tmp_member, member); - convert_to_string(&tmp_member); + ZVAL_STR(&tmp_member, zval_get_string_func(member)); member = &tmp_member; cache_slot = NULL; } @@ -969,12 +973,11 @@ static int php_zip_has_property(zval *object, zval *member, int type, void **cac zval_ptr_dtor(&tmp); } else { - std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->has_property(object, member, type, cache_slot); + retval = zend_std_has_property(object, member, type, cache_slot); } if (member == &tmp_member) { - zval_dtor(member); + zval_ptr_dtor_str(&tmp_member); } return retval; @@ -1055,7 +1058,7 @@ static zend_object *php_zip_object_new(zend_class_entry *class_type) /* {{{ */ { ze_zip_object *intern; - intern = ecalloc(1, sizeof(ze_zip_object) + zend_object_properties_size(class_type)); + intern = zend_object_alloc(sizeof(ze_zip_object), class_type); intern->prop_handler = &zip_prop_handlers; zend_object_std_init(&intern->zo, class_type); object_properties_init(&intern->zo, class_type); @@ -1322,7 +1325,7 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_read) ZSTR_LEN(buffer) = n; RETURN_NEW_STR(buffer); } else { - zend_string_free(buffer); + zend_string_efree(buffer); RETURN_EMPTY_STRING() } } else { @@ -1743,7 +1746,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* if ((add_path_len + file_stripped_len) > MAXPATHLEN) { php_error_docref(NULL, E_WARNING, "Entry name too long (max: %d, %zd given)", MAXPATHLEN - 1, (add_path_len + file_stripped_len)); - zval_ptr_dtor(return_value); + zend_array_destroy(Z_ARR_P(return_value)); RETURN_FALSE; } snprintf(entry_name_buf, MAXPATHLEN, "%s%s", add_path, file_stripped); @@ -1754,13 +1757,13 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* entry_name = entry_name_buf; entry_name_len = strlen(entry_name); if (basename) { - zend_string_release(basename); + zend_string_release_ex(basename, 0); basename = NULL; } if (php_zip_add_file(intern, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file), entry_name, entry_name_len, 0, 0) < 0) { - zval_dtor(return_value); + zend_array_destroy(Z_ARR_P(return_value)); RETURN_FALSE; } } @@ -2260,9 +2263,9 @@ static ZIPARCHIVE_METHOD(getExternalAttributesIndex) (zip_flags_t)flags, &opsys, &attr) < 0) { RETURN_FALSE; } - zval_dtor(z_opsys); + zval_ptr_dtor(z_opsys); ZVAL_LONG(z_opsys, opsys); - zval_dtor(z_attr); + zval_ptr_dtor(z_attr); ZVAL_LONG(z_attr, attr); RETURN_TRUE; } @@ -2854,7 +2857,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ buffer = zend_string_safe_alloc(1, len, 0, 0); n = zip_fread(zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer)); if (n < 1) { - zend_string_free(buffer); + zend_string_efree(buffer); RETURN_EMPTY_STRING(); } @@ -3150,7 +3153,7 @@ static PHP_MINIT_FUNCTION(zip) { zend_class_entry ce; - memcpy(&zip_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + memcpy(&zip_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); zip_object_handlers.offset = XtOffsetOf(ze_zip_object, zo); zip_object_handlers.free_obj = php_zip_object_free_storage; zip_object_handlers.clone_obj = NULL; |