From: Anatol Belski Date: Sat, 27 Aug 2016 20:28:13 +0000 (+0200) Subject: fix leak X-Git-Tag: php-7.1.0RC1~53 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=92a60a67cf5abab1d4f68965699b10a0edc47282;p=php fix leak --- diff --git a/win32/ioutil.c b/win32/ioutil.c index b661a150af..64c8a706d4 100644 --- a/win32/ioutil.c +++ b/win32/ioutil.c @@ -193,7 +193,7 @@ PW32IO int php_win32_ioutil_open_w(const wchar_t *path, int flags, ...) int fd; mode_t mode = 0; - PHP_WIN32_IOUTIL_CHECK_PATH_W(path, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(path, -1, 0) if (flags & O_CREAT) { va_list arg; @@ -291,7 +291,7 @@ PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode) int ret = 0; DWORD err = 0; - PHP_WIN32_IOUTIL_CHECK_PATH_W(path, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(path, -1, 0) /* TODO extend with mode usage */ if (!CreateDirectoryW(path, NULL)) { @@ -316,7 +316,7 @@ PW32IO int php_win32_ioutil_mkdir(const char *path, mode_t mode) return -1; } - PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 0) if (!CreateDirectoryW(pathw, NULL)) { err = GetLastError(); @@ -336,7 +336,7 @@ PW32IO int php_win32_ioutil_unlink_w(const wchar_t *path) int ret = 0; DWORD err = 0; - PHP_WIN32_IOUTIL_CHECK_PATH_W(path, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(path, -1, 0) if (!DeleteFileW(path)) { err = GetLastError(); @@ -352,7 +352,7 @@ PW32IO int php_win32_ioutil_rmdir_w(const wchar_t *path) int ret = 0; DWORD err = 0; - PHP_WIN32_IOUTIL_CHECK_PATH_W(path, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(path, -1, 0) if (!RemoveDirectoryW(path)) { err = GetLastError(); @@ -382,8 +382,8 @@ PW32IO int php_win32_ioutil_rename_w(const wchar_t *oldname, const wchar_t *newn int ret = 0; DWORD err = 0; - PHP_WIN32_IOUTIL_CHECK_PATH_W(oldname, -1) - PHP_WIN32_IOUTIL_CHECK_PATH_W(newname, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(oldname, -1, 0) + PHP_WIN32_IOUTIL_CHECK_PATH_W(newname, -1, 0) if (!MoveFileExW(oldname, newname, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED)) { diff --git a/win32/ioutil.h b/win32/ioutil.h index ea40db4c66..15c8f0e339 100644 --- a/win32/ioutil.h +++ b/win32/ioutil.h @@ -128,11 +128,15 @@ typedef enum { pathw = php_win32_ioutil_any_to_w(path); \ } while (0); -#define PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, ret) do { \ - size_t len = wcslen(pathw); \ - if (len >= 1 && L' ' == pathw[len-1] || \ - len > 1 && !PHP_WIN32_IOUTIL_IS_SLASHW(pathw[len-2]) && L'.' != pathw[len-2] && L'.' == pathw[len-1] \ - ) { \ +#define PHP_WIN32_IOUTIL_PATH_IS_OK_W(pathw, len) \ + (!((len) >= 1 && L' ' == pathw[(len)-1] || \ + (len) > 1 && !PHP_WIN32_IOUTIL_IS_SLASHW(pathw[(len)-2]) && L'.' != pathw[(len)-2] && L'.' == pathw[(len)-1])) + +#define PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, ret, dealloc) do { \ + if (!PHP_WIN32_IOUTIL_PATH_IS_OK_W(pathw, wcslen(pathw))) { \ + if (dealloc) { \ + free(pathw); \ + } \ SET_ERRNO_FROM_WIN32_CODE(ERROR_ACCESS_DENIED); \ return ret; \ } \ @@ -237,7 +241,7 @@ __forceinline static int php_win32_ioutil_access(const char *path, mode_t mode) return -1; } - PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1) ret = _waccess(pathw, mode); _get_errno(&err); @@ -262,7 +266,7 @@ __forceinline static int php_win32_ioutil_open(const char *path, int flags, ...) return -1; } - PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1) if (flags & O_CREAT) { va_list arg; @@ -294,7 +298,7 @@ __forceinline static int php_win32_ioutil_unlink(const char *path) return -1; } - PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1) if (!DeleteFileW(pathw)) { err = GetLastError(); @@ -320,7 +324,7 @@ __forceinline static int php_win32_ioutil_rmdir(const char *path) return -1; } - PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1) if (!RemoveDirectoryW(pathw)) { err = GetLastError(); @@ -342,18 +346,24 @@ fdopen() might be the way, if we learn how to convert the mode options (maybe gr __forceinline static FILE *php_win32_ioutil_fopen(const char *patha, const char *modea) {/*{{{*/ FILE *ret; - wchar_t *pathw = php_win32_ioutil_any_to_w(patha); - wchar_t *modew = php_win32_ioutil_ascii_to_w(modea); + wchar_t *pathw; + wchar_t *modew; int err = 0; - if (!pathw || !modew) { - free(pathw); - free(modew); + pathw = php_win32_ioutil_any_to_w(patha); + if (!pathw) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return NULL; } - PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, NULL) + PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, NULL, 1) + + modew = php_win32_ioutil_ascii_to_w(modea); + if (!modew) { + free(pathw); + SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); + return NULL; + } ret = _wfopen(pathw, modew); _get_errno(&err); @@ -368,20 +378,29 @@ __forceinline static FILE *php_win32_ioutil_fopen(const char *patha, const char __forceinline static int php_win32_ioutil_rename(const char *oldnamea, const char *newnamea) {/*{{{*/ - wchar_t *oldnamew = php_win32_ioutil_any_to_w(oldnamea); - wchar_t *newnamew = php_win32_ioutil_any_to_w(newnamea); + wchar_t *oldnamew; + wchar_t *newnamew; int ret; DWORD err = 0; - if (!oldnamew || !newnamew) { - free(oldnamew); - free(newnamew); + oldnamew = php_win32_ioutil_any_to_w(oldnamea); + if (!oldnamew) { SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); return -1; } + PHP_WIN32_IOUTIL_CHECK_PATH_W(oldnamew, -1, 1) - PHP_WIN32_IOUTIL_CHECK_PATH_W(oldnamew, -1) - PHP_WIN32_IOUTIL_CHECK_PATH_W(newnamew, -1) + newnamew = php_win32_ioutil_any_to_w(newnamea); + if (!newnamew) { + free(oldnamew); + SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); + return -1; + } else if (!PHP_WIN32_IOUTIL_PATH_IS_OK_W(newnamew, wcslen(newnamew))) { + free(oldnamew); + free(newnamew); + SET_ERRNO_FROM_WIN32_CODE(ERROR_ACCESS_DENIED); + return -1; + } ret = php_win32_ioutil_rename_w(oldnamew, newnamew); err = GetLastError(); @@ -471,7 +490,7 @@ __forceinline static int php_win32_ioutil_chmod(const char *patha, int mode) return -1; } - PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1) + PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1) ret = _wchmod(pathw, mode); _get_errno(&err);