Skip to content

Commit

Permalink
Fix potential OPcache file cache related issues
Browse files Browse the repository at this point in the history
To solve issues detected during testing, we backport the following
commits to PHP 7.2:

129c5c1
9ac133a
ce72bc6
  • Loading branch information
weltling authored and cmb69 committed Apr 11, 2019
1 parent f31d7ca commit 5477d68
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 11 deletions.
10 changes: 9 additions & 1 deletion ext/opcache/zend_file_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
46 changes: 36 additions & 10 deletions win32/ioutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand Down

0 comments on commit 5477d68

Please sign in to comment.