diff options
author | Anatol Belski <ab@php.net> | 2019-04-11 18:17:03 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2019-04-11 18:28:49 +0200 |
commit | 5477d683008790dc47a13901f9d8acd6332955ae (patch) | |
tree | 67932976d9afa2a1393fd8a05baca42394562e81 | |
parent | f31d7ca85e400b85c06adb8db24c573dc1d98dbb (diff) | |
download | php-git-5477d683008790dc47a13901f9d8acd6332955ae.tar.gz |
Fix potential OPcache file cache related issues
To solve issues detected during testing, we backport the following
commits to PHP 7.2:
129c5c1181bf344b37e13fd6dc5dfe76c13d7208
9ac133a0b3863ca4d9659140154ee237e5f4669a
ce72bc6b658c335dd37393d0beb28584e6805e97
-rw-r--r-- | ext/opcache/zend_file_cache.c | 10 | ||||
-rw-r--r-- | win32/ioutil.c | 46 |
2 files changed, 45 insertions, 11 deletions
diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index c00f1534dc..20f21d6a83 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -169,7 +169,11 @@ static int zend_file_cache_mkdir(char *filename, size_t start) if (IS_SLASH(*s)) { char old = *s; *s = '\000'; +#ifndef ZEND_WIN32 if (mkdir(filename, S_IRWXU) < 0 && errno != EEXIST) { +#else + if (php_win32_ioutil_mkdir(filename, 0700) < 0 && errno != EEXIST) { +#endif *s = old; return FAILURE; } @@ -827,7 +831,7 @@ int zend_file_cache_script_store(zend_persistent_script *script, int in_shm) #ifndef ZEND_WIN32 fd = open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR); #else - fd = open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, _S_IREAD | _S_IWRITE); + fd = php_win32_ioutil_open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, _S_IREAD | _S_IWRITE); #endif if (fd < 0) { if (errno != EEXIST) { @@ -1374,7 +1378,11 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl } filename = zend_file_cache_get_bin_file_path(full_path); +#ifndef ZEND_WIN32 fd = open(filename, O_RDONLY | O_BINARY); +#else + fd = php_win32_ioutil_open(filename, O_RDONLY | O_BINARY); +#endif if (fd < 0) { efree(filename); return NULL; diff --git a/win32/ioutil.c b/win32/ioutil.c index 07dc70d917..c454c19535 100644 --- a/win32/ioutil.c +++ b/win32/ioutil.c @@ -321,20 +321,41 @@ PW32IO int php_win32_ioutil_mkdir(const char *path, mode_t mode) already needs to be a long path. The given path is already normalized and prepared, need only to prefix it. */ - wchar_t *tmp = (wchar_t *) malloc((pathw_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t)); + wchar_t *tmp = (wchar_t *) malloc((pathw_len + 1) * sizeof(wchar_t)); if (!tmp) { free(pathw); SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY); return -1; } + memmove(tmp, pathw, (pathw_len + 1) * sizeof(wchar_t)); - memmove(tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t)); - memmove(tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, pathw, pathw_len * sizeof(wchar_t)); - pathw_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; - tmp[pathw_len] = L'\0'; + if (PHP_WIN32_IOUTIL_NORM_FAIL == php_win32_ioutil_normalize_path_w(&tmp, pathw_len, &pathw_len)) { + free(tmp); + return -1; + } free(pathw); pathw = tmp; + + if (!PHP_WIN32_IOUTIL_IS_LONG_PATHW(tmp, pathw_len)) { + wchar_t *_tmp = (wchar_t *) malloc((pathw_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t)); + if (!_tmp) { + SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY); + free(tmp); + return -1; + } + memmove(_tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t)); + memmove(_tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, tmp, pathw_len * sizeof(wchar_t)); + pathw_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; + _tmp[pathw_len] = L'\0'; + free(tmp); + tmp = _tmp; + } + + pathw = tmp; + + } else { + pathw = pathw; } /* TODO extend with mode usage */ @@ -541,7 +562,7 @@ PW32IO size_t php_win32_ioutil_dirname(char *path, size_t len) /* Partial normalization can still be acceptable, explicit fail has to be caught. */ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len) {/*{{{*/ - wchar_t *pos, *idx = *buf, canonicalw[MAXPATHLEN]; + wchar_t *idx = *buf, canonicalw[MAXPATHLEN], _tmp[MAXPATHLEN], *pos = _tmp; size_t ret_len = len; if (len >= MAXPATHLEN) { @@ -550,12 +571,17 @@ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(w return PHP_WIN32_IOUTIL_NORM_FAIL; } - while (NULL != (pos = wcschr(idx, PHP_WIN32_IOUTIL_FW_SLASHW)) && (size_t)(idx - *buf) <= len) { - *pos = PHP_WIN32_IOUTIL_DEFAULT_SLASHW; - idx = pos++; + for (; (size_t)(idx - *buf) <= len; idx++, pos++) { + *pos = *idx; + if (PHP_WIN32_IOUTIL_FW_SLASHW == *pos) { + *pos = PHP_WIN32_IOUTIL_DEFAULT_SLASHW; + } + while (PHP_WIN32_IOUTIL_IS_SLASHW(*idx) && PHP_WIN32_IOUTIL_IS_SLASHW(*(idx+1))) { + idx++; + } } - if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf, PATHCCH_ALLOW_LONG_PATHS)) { + if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, _tmp, PATHCCH_ALLOW_LONG_PATHS)) { /* Length unchanged. */ *new_len = len; return PHP_WIN32_IOUTIL_NORM_PARTIAL; |