From: Nikita Popov Date: Thu, 6 Jun 2019 09:46:23 +0000 (+0200) Subject: php_zip_pcre: Match pattern before stating for directories X-Git-Tag: php-7.4.0alpha1~72 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3372f2cf2cd90e899c3b412ec38f2eebc7e106b3;p=php 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. --- 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); }