-
Notifications
You must be signed in to change notification settings - Fork 8k
ext/zip: further micro optimisations. #20362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
37575e9
39ac723
480a1d8
f45b893
3e05fa4
2cd1368
c7d0dae
a6925a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,6 +74,17 @@ static int le_zip_entry; | |
| # define add_ascii_assoc_string add_assoc_string | ||
| # define add_ascii_assoc_long add_assoc_long | ||
|
|
||
| static bool php_zip_file_set_encryption(struct zip *intern, zend_long index, zend_long method, char *password) { | ||
| // FIXME: is a workaround to reset/free the password in case of consecutive calls. | ||
| // when libzip 1.11.5 is available, we can save this call in this case. | ||
| if (UNEXPECTED(zip_file_set_encryption(intern, (zip_uint64_t)index, ZIP_EM_NONE, NULL) < 0)) { | ||
| php_error_docref(NULL, E_WARNING, "password reset failed"); | ||
| return false; | ||
| } | ||
|
|
||
| return (zip_file_set_encryption(intern, (zip_uint64_t)index, (zip_uint16_t)method, password) == 0); | ||
| } | ||
|
|
||
| /* Flatten a path by making a relative path (to .)*/ | ||
| static char * php_zip_make_relative_path(char *path, size_t path_len) /* {{{ */ | ||
| { | ||
|
|
@@ -367,14 +378,22 @@ static zend_result php_zip_parse_options(HashTable *options, zip_options *opts) | |
| php_error_docref(NULL, E_WARNING, "Option \"comp_method\" must be of type int, %s given", | ||
| zend_zval_value_name(option)); | ||
| } | ||
| opts->comp_method = zval_get_long(option); | ||
| zend_long comp_method = zval_get_long(option); | ||
| if (comp_method < 0 || comp_method > INT_MAX) { | ||
| php_error_docref(NULL, E_WARNING, "Option \"comp_method\" must be between 0 and %d", INT_MAX); | ||
| } | ||
| opts->comp_method = (zip_int32_t)comp_method; | ||
|
|
||
| if ((option = zend_hash_str_find(options, "comp_flags", sizeof("comp_flags") - 1)) != NULL) { | ||
| if (Z_TYPE_P(option) != IS_LONG) { | ||
| php_error_docref(NULL, E_WARNING, "Option \"comp_flags\" must be of type int, %s given", | ||
| zend_zval_value_name(option)); | ||
| } | ||
| opts->comp_flags = zval_get_long(option); | ||
| zend_long comp_flags = zval_get_long(option); | ||
| if (comp_flags < 0 || comp_flags > USHRT_MAX) { | ||
| php_error_docref(NULL, E_WARNING, "Option \"comp_flags\" must be between 0 and %u", USHRT_MAX); | ||
| } | ||
| opts->comp_flags = (zip_uint32_t)comp_flags; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1752,12 +1771,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* | |
| } | ||
| #ifdef HAVE_ENCRYPTION | ||
| if (opts.enc_method >= 0) { | ||
| if (UNEXPECTED(zip_file_set_encryption(ze_obj->za, ze_obj->last_id, ZIP_EM_NONE, NULL) < 0)) { | ||
| zend_array_destroy(Z_ARR_P(return_value)); | ||
| php_error_docref(NULL, E_WARNING, "password reset failed"); | ||
| RETURN_FALSE; | ||
| } | ||
| if (zip_file_set_encryption(ze_obj->za, ze_obj->last_id, opts.enc_method, opts.enc_password)) { | ||
| if (!php_zip_file_set_encryption(ze_obj->za, ze_obj->last_id, opts.enc_method, opts.enc_password)) { | ||
| zend_array_destroy(Z_ARR_P(return_value)); | ||
| RETURN_FALSE; | ||
| } | ||
|
|
@@ -2280,15 +2294,7 @@ PHP_METHOD(ZipArchive, setEncryptionName) | |
| RETURN_FALSE; | ||
| } | ||
|
|
||
| if (UNEXPECTED(zip_file_set_encryption(intern, idx, ZIP_EM_NONE, NULL) < 0)) { | ||
| php_error_docref(NULL, E_WARNING, "password reset failed"); | ||
| RETURN_FALSE; | ||
| } | ||
|
|
||
| if (zip_file_set_encryption(intern, idx, (zip_uint16_t)method, password)) { | ||
| RETURN_FALSE; | ||
| } | ||
| RETURN_TRUE; | ||
| RETURN_BOOL(php_zip_file_set_encryption(intern, idx, method, password)); | ||
| } | ||
| /* }}} */ | ||
|
|
||
|
|
@@ -2308,12 +2314,7 @@ PHP_METHOD(ZipArchive, setEncryptionIndex) | |
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| if (UNEXPECTED(zip_file_set_encryption(intern, index, ZIP_EM_NONE, NULL) < 0)) { | ||
| php_error_docref(NULL, E_WARNING, "password reset failed"); | ||
| RETURN_FALSE; | ||
| } | ||
|
|
||
| RETURN_BOOL(zip_file_set_encryption(intern, index, (zip_uint16_t)method, password) == 0); | ||
| RETURN_BOOL(php_zip_file_set_encryption(intern, index, method, password)); | ||
| } | ||
| /* }}} */ | ||
| #endif | ||
|
|
@@ -2391,13 +2392,23 @@ PHP_METHOD(ZipArchive, setCompressionName) | |
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, this); | ||
|
|
||
| if (name_len == 0) { | ||
| zend_argument_must_not_be_empty_error(1); | ||
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| if (comp_method < -1 || comp_method > INT_MAX) { | ||
| zend_argument_value_error(2, "must be between -1 and %d", INT_MAX); | ||
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| if (comp_flags < 0 || comp_flags > USHRT_MAX) { | ||
| // comp_flags is cast down accordingly in libzip, zip_entry_t compression_level is of zip_uint16_t | ||
| zend_argument_value_error(3, "must be between 0 and %u", USHRT_MAX); | ||
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, this); | ||
| idx = zip_name_locate(intern, name, 0); | ||
|
|
||
| if (idx < 0) { | ||
|
|
@@ -2422,6 +2433,21 @@ PHP_METHOD(ZipArchive, setCompressionIndex) | |
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| if (index < 0) { | ||
| RETURN_FALSE; | ||
| } | ||
|
|
||
| if (comp_method < -1 || comp_method > INT_MAX) { | ||
| zend_argument_value_error(2, "must be between -1 and %d", INT_MAX); | ||
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| if (comp_flags < 0 || comp_flags > USHRT_MAX) { | ||
| // comp_flags is cast down accordingly in libzip, zip_entry_t compression_level is of zip_uint16_t | ||
| zend_argument_value_error(3, "must be between 0 and %u", USHRT_MAX); | ||
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, this); | ||
|
|
||
| RETURN_BOOL(zip_set_file_compression(intern, (zip_uint64_t)index, | ||
|
|
@@ -2444,13 +2470,13 @@ PHP_METHOD(ZipArchive, setMtimeName) | |
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, this); | ||
|
|
||
| if (name_len == 0) { | ||
| zend_argument_must_not_be_empty_error(1); | ||
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, this); | ||
|
|
||
| idx = zip_name_locate(intern, name, 0); | ||
|
|
||
| if (idx < 0) { | ||
|
|
@@ -2516,17 +2542,15 @@ PHP_METHOD(ZipArchive, deleteName) | |
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| if (name_len < 1) { | ||
| RETURN_FALSE; | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb); | ||
| if (zip_delete(intern, sb.index)) { | ||
| RETURN_FALSE; | ||
| } | ||
| RETURN_TRUE; | ||
|
|
||
| RETURN_BOOL(zip_delete(intern, sb.index) == 0); | ||
| } | ||
| /* }}} */ | ||
|
|
||
|
|
@@ -2547,13 +2571,13 @@ PHP_METHOD(ZipArchive, renameIndex) | |
| RETURN_FALSE; | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| if (new_name_len == 0) { | ||
| zend_argument_must_not_be_empty_error(2); | ||
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| RETURN_BOOL(zip_file_rename(intern, index, (const char *)new_name, 0) == 0); | ||
| } | ||
| /* }}} */ | ||
|
|
@@ -2595,12 +2619,12 @@ PHP_METHOD(ZipArchive, unchangeIndex) | |
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| if (index < 0) { | ||
| RETURN_FALSE; | ||
| } | ||
|
Comment on lines
2622
to
2624
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it might make sense to make those sorts of conditions a warning/value error in the future?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I kept "api compatible" for now on purpose. |
||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| RETURN_BOOL(zip_unchange(intern, index) == 0); | ||
| } | ||
| /* }}} */ | ||
|
|
@@ -2618,12 +2642,12 @@ PHP_METHOD(ZipArchive, unchangeName) | |
| RETURN_THROWS(); | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| if (name_len < 1) { | ||
| RETURN_FALSE; | ||
| } | ||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| PHP_ZIP_STAT_PATH(intern, name, name_len, 0, sb); | ||
|
|
||
| RETURN_BOOL(zip_unchange(intern, sb.index) == 0); | ||
|
|
@@ -2687,8 +2711,6 @@ PHP_METHOD(ZipArchive, extractTo) | |
| Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(files_ht, files_str) | ||
| ZEND_PARSE_PARAMETERS_END(); | ||
|
|
||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| if (pathto_len < 1) { | ||
| RETURN_FALSE; | ||
| } | ||
|
|
@@ -2701,6 +2723,7 @@ PHP_METHOD(ZipArchive, extractTo) | |
| } | ||
|
|
||
| uint32_t nelems, i; | ||
| ZIP_FROM_OBJECT(intern, self); | ||
|
|
||
| if (files_str) { | ||
| if (!php_zip_extract_file(intern, pathto, ZSTR_VAL(files_str), ZSTR_LEN(files_str), -1)) { | ||
|
|
@@ -2797,7 +2820,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ | |
| RETURN_FALSE; | ||
| } | ||
|
|
||
| buffer = zend_string_safe_alloc(1, len, 0, 0); | ||
| buffer = zend_string_safe_alloc(1, len, 0, false); | ||
| n = zip_fread(zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer)); | ||
| if (n < 1) { | ||
| zend_string_efree(buffer); | ||
|
|
@@ -3006,6 +3029,10 @@ PHP_METHOD(ZipArchive, isCompressionMethodSupported) | |
| if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|b", &method, &enc) == FAILURE) { | ||
| return; | ||
| } | ||
| if (method < -1 || method > INT_MAX) { | ||
| zend_argument_value_error(1, "must be between -1 and %d", INT_MAX); | ||
| RETURN_THROWS(); | ||
| } | ||
| RETVAL_BOOL(zip_compression_method_supported((zip_int32_t)method, enc)); | ||
| } | ||
| /* }}} */ | ||
|
|
@@ -3019,7 +3046,11 @@ PHP_METHOD(ZipArchive, isEncryptionMethodSupported) | |
| if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|b", &method, &enc) == FAILURE) { | ||
| return; | ||
| } | ||
| RETVAL_BOOL(zip_encryption_method_supported((zip_uint16_t)method, enc)); | ||
| if (method < 0 || method > USHRT_MAX) { | ||
| zend_argument_value_error(1, "must be between 0 and %u", USHRT_MAX); | ||
| RETURN_THROWS(); | ||
| } | ||
| RETURN_BOOL(zip_encryption_method_supported((zip_uint16_t)method, enc)); | ||
| } | ||
| /* }}} */ | ||
| #endif | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another follow-up I'd like to see is to use
zval_try_get_long():)