Skip to content

Commit 5477d68

Browse files
weltlingcmb69
authored andcommitted
Fix potential OPcache file cache related issues
To solve issues detected during testing, we backport the following commits to PHP 7.2: 129c5c1 9ac133a ce72bc6
1 parent f31d7ca commit 5477d68

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

ext/opcache/zend_file_cache.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,11 @@ static int zend_file_cache_mkdir(char *filename, size_t start)
169169
if (IS_SLASH(*s)) {
170170
char old = *s;
171171
*s = '\000';
172+
#ifndef ZEND_WIN32
172173
if (mkdir(filename, S_IRWXU) < 0 && errno != EEXIST) {
174+
#else
175+
if (php_win32_ioutil_mkdir(filename, 0700) < 0 && errno != EEXIST) {
176+
#endif
173177
*s = old;
174178
return FAILURE;
175179
}
@@ -827,7 +831,7 @@ int zend_file_cache_script_store(zend_persistent_script *script, int in_shm)
827831
#ifndef ZEND_WIN32
828832
fd = open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR);
829833
#else
830-
fd = open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, _S_IREAD | _S_IWRITE);
834+
fd = php_win32_ioutil_open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, _S_IREAD | _S_IWRITE);
831835
#endif
832836
if (fd < 0) {
833837
if (errno != EEXIST) {
@@ -1374,7 +1378,11 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
13741378
}
13751379
filename = zend_file_cache_get_bin_file_path(full_path);
13761380

1381+
#ifndef ZEND_WIN32
13771382
fd = open(filename, O_RDONLY | O_BINARY);
1383+
#else
1384+
fd = php_win32_ioutil_open(filename, O_RDONLY | O_BINARY);
1385+
#endif
13781386
if (fd < 0) {
13791387
efree(filename);
13801388
return NULL;

win32/ioutil.c

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,20 +321,41 @@ PW32IO int php_win32_ioutil_mkdir(const char *path, mode_t mode)
321321
already needs to be a long path. The given path is already normalized
322322
and prepared, need only to prefix it.
323323
*/
324-
wchar_t *tmp = (wchar_t *) malloc((pathw_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t));
324+
wchar_t *tmp = (wchar_t *) malloc((pathw_len + 1) * sizeof(wchar_t));
325325
if (!tmp) {
326326
free(pathw);
327327
SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
328328
return -1;
329329
}
330+
memmove(tmp, pathw, (pathw_len + 1) * sizeof(wchar_t));
330331

331-
memmove(tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t));
332-
memmove(tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, pathw, pathw_len * sizeof(wchar_t));
333-
pathw_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
334-
tmp[pathw_len] = L'\0';
332+
if (PHP_WIN32_IOUTIL_NORM_FAIL == php_win32_ioutil_normalize_path_w(&tmp, pathw_len, &pathw_len)) {
333+
free(tmp);
334+
return -1;
335+
}
335336

336337
free(pathw);
337338
pathw = tmp;
339+
340+
if (!PHP_WIN32_IOUTIL_IS_LONG_PATHW(tmp, pathw_len)) {
341+
wchar_t *_tmp = (wchar_t *) malloc((pathw_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t));
342+
if (!_tmp) {
343+
SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
344+
free(tmp);
345+
return -1;
346+
}
347+
memmove(_tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t));
348+
memmove(_tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, tmp, pathw_len * sizeof(wchar_t));
349+
pathw_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
350+
_tmp[pathw_len] = L'\0';
351+
free(tmp);
352+
tmp = _tmp;
353+
}
354+
355+
pathw = tmp;
356+
357+
} else {
358+
pathw = pathw;
338359
}
339360

340361
/* TODO extend with mode usage */
@@ -541,7 +562,7 @@ PW32IO size_t php_win32_ioutil_dirname(char *path, size_t len)
541562
/* Partial normalization can still be acceptable, explicit fail has to be caught. */
542563
PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len)
543564
{/*{{{*/
544-
wchar_t *pos, *idx = *buf, canonicalw[MAXPATHLEN];
565+
wchar_t *idx = *buf, canonicalw[MAXPATHLEN], _tmp[MAXPATHLEN], *pos = _tmp;
545566
size_t ret_len = len;
546567

547568
if (len >= MAXPATHLEN) {
@@ -550,12 +571,17 @@ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(w
550571
return PHP_WIN32_IOUTIL_NORM_FAIL;
551572
}
552573

553-
while (NULL != (pos = wcschr(idx, PHP_WIN32_IOUTIL_FW_SLASHW)) && (size_t)(idx - *buf) <= len) {
554-
*pos = PHP_WIN32_IOUTIL_DEFAULT_SLASHW;
555-
idx = pos++;
574+
for (; (size_t)(idx - *buf) <= len; idx++, pos++) {
575+
*pos = *idx;
576+
if (PHP_WIN32_IOUTIL_FW_SLASHW == *pos) {
577+
*pos = PHP_WIN32_IOUTIL_DEFAULT_SLASHW;
578+
}
579+
while (PHP_WIN32_IOUTIL_IS_SLASHW(*idx) && PHP_WIN32_IOUTIL_IS_SLASHW(*(idx+1))) {
580+
idx++;
581+
}
556582
}
557583

558-
if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf, PATHCCH_ALLOW_LONG_PATHS)) {
584+
if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, _tmp, PATHCCH_ALLOW_LONG_PATHS)) {
559585
/* Length unchanged. */
560586
*new_len = len;
561587
return PHP_WIN32_IOUTIL_NORM_PARTIAL;

0 commit comments

Comments
 (0)