From 3372f2cf2cd90e899c3b412ec38f2eebc7e106b3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 6 Jun 2019 11:46:23 +0200 Subject: [PATCH] php_zip_pcre: Match pattern before stating for directories For two reasons: First, it's generally cheaper to match a regex than perform a stat (especially on Windows). Second, it will not fail on concurrent modification of a directory in parts that are not matched by the pattern, such as the spurious failure in ext/zip/tests/bug72660.phpt. --- ext/zip/php_zip.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index b8e01c1fe2..fabd30e8ea 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -677,19 +677,6 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val break; } - snprintf(fullpath, MAXPATHLEN, "%s%c%s", path, DEFAULT_SLASH, ZSTR_VAL(namelist[i])); - - if (0 != VCWD_STAT(fullpath, &s)) { - php_error_docref(NULL, E_WARNING, "Cannot read <%s>", fullpath); - zend_string_release_ex(namelist[i], 0); - continue; - } - - if (S_IFDIR == (s.st_mode & S_IFMT)) { - zend_string_release_ex(namelist[i], 0); - continue; - } - match_data = php_pcre_create_match_data(capture_count, re); if (!match_data) { /* Allocation failed, but can proceed to the next pattern. */ @@ -704,6 +691,19 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val continue; } + snprintf(fullpath, MAXPATHLEN, "%s%c%s", path, DEFAULT_SLASH, ZSTR_VAL(namelist[i])); + + if (0 != VCWD_STAT(fullpath, &s)) { + php_error_docref(NULL, E_WARNING, "Cannot read <%s>", fullpath); + zend_string_release_ex(namelist[i], 0); + continue; + } + + if (S_IFDIR == (s.st_mode & S_IFMT)) { + zend_string_release_ex(namelist[i], 0); + continue; + } + add_next_index_string(return_value, fullpath); zend_string_release_ex(namelist[i], 0); } -- 2.50.1