Skip to content

Commit ce72bc6

Browse files
committed
Ensure double slashes are replaced by the path normalization
1 parent 1aa30bb commit ce72bc6

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

win32/ioutil.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,18 +306,35 @@ PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode)
306306
already needs to be a long path. The given path is already normalized
307307
and prepared, need only to prefix it.
308308
*/
309-
wchar_t *tmp = (wchar_t *) malloc((path_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t));
309+
wchar_t *tmp = (wchar_t *) malloc((path_len + 1) * sizeof(wchar_t));
310310
if (!tmp) {
311311
SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
312312
return -1;
313313
}
314+
memmove(tmp, path, (path_len + 1) * sizeof(wchar_t));
314315

315-
memmove(tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t));
316-
memmove(tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, path, path_len * sizeof(wchar_t));
317-
path_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
318-
tmp[path_len] = L'\0';
316+
if (PHP_WIN32_IOUTIL_NORM_FAIL == php_win32_ioutil_normalize_path_w(&tmp, path_len, &path_len)) {
317+
free(tmp);
318+
return -1;
319+
}
320+
321+
if (!PHP_WIN32_IOUTIL_IS_LONG_PATHW(tmp, path_len)) {
322+
wchar_t *_tmp = (wchar_t *) malloc((path_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t));
323+
if (!_tmp) {
324+
SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
325+
free(tmp);
326+
return -1;
327+
}
328+
memmove(_tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t));
329+
memmove(_tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, tmp, path_len * sizeof(wchar_t));
330+
path_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
331+
_tmp[path_len] = L'\0';
332+
free(tmp);
333+
tmp = _tmp;
334+
}
319335

320336
my_path = tmp;
337+
321338
} else {
322339
my_path = path;
323340
}
@@ -573,7 +590,7 @@ PW32IO size_t php_win32_ioutil_dirname(char *path, size_t len)
573590
/* Partial normalization can still be acceptable, explicit fail has to be caught. */
574591
PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len)
575592
{/*{{{*/
576-
wchar_t *pos, *idx = *buf, canonicalw[MAXPATHLEN];
593+
wchar_t *idx = *buf, canonicalw[MAXPATHLEN], _tmp[MAXPATHLEN], *pos = _tmp;
577594
size_t ret_len = len;
578595

579596
if (len >= MAXPATHLEN) {
@@ -582,12 +599,17 @@ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(w
582599
return PHP_WIN32_IOUTIL_NORM_FAIL;
583600
}
584601

585-
while (NULL != (pos = wcschr(idx, PHP_WIN32_IOUTIL_FW_SLASHW)) && (size_t)(idx - *buf) <= len) {
586-
*pos = PHP_WIN32_IOUTIL_DEFAULT_SLASHW;
587-
idx = pos++;
602+
for (; (size_t)(idx - *buf) <= len; idx++, pos++) {
603+
*pos = *idx;
604+
if (PHP_WIN32_IOUTIL_FW_SLASHW == *pos) {
605+
*pos = PHP_WIN32_IOUTIL_DEFAULT_SLASHW;
606+
}
607+
while (PHP_WIN32_IOUTIL_IS_SLASHW(*idx) && PHP_WIN32_IOUTIL_IS_SLASHW(*(idx+1))) {
608+
idx++;
609+
}
588610
}
589611

590-
if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf, PATHCCH_ALLOW_LONG_PATHS)) {
612+
if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, _tmp, PATHCCH_ALLOW_LONG_PATHS)) {
591613
/* Length unchanged. */
592614
*new_len = len;
593615
return PHP_WIN32_IOUTIL_NORM_PARTIAL;

0 commit comments

Comments
 (0)