summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--win32/ioutil.c41
-rw-r--r--win32/ioutil.h12
2 files changed, 31 insertions, 22 deletions
diff --git a/win32/ioutil.c b/win32/ioutil.c
index 1bf88c44b8..fc4413b2dd 100644
--- a/win32/ioutil.c
+++ b/win32/ioutil.c
@@ -66,7 +66,7 @@
#include <winnls.h>
*/
-typedef HRESULT (WINAPI *MyPathCchCanonicalizeEx)(wchar_t *pszPathOut, size_t cchPathOut, const wchar_t *pszPathIn, unsigned long dwFlags);
+typedef HRESULT (__stdcall *MyPathCchCanonicalizeEx)(wchar_t *pszPathOut, size_t cchPathOut, const wchar_t *pszPathIn, unsigned long dwFlags);
static MyPathCchCanonicalizeEx canonicalize_path_w = NULL;
@@ -506,14 +506,14 @@ PW32IO size_t php_win32_ioutil_dirname(char *path, size_t len)
return ret_len;
}/*}}}*/
-PW32IO BOOL php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len)
+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];
- size_t ret_len = len, canonicalw_len, shift;
+ size_t ret_len = len;
if (len >= MAXPATHLEN) {
- SET_ERRNO_FROM_WIN32_CODE(ERROR_BUFFER_OVERFLOW);
- return FALSE;
+ SET_ERRNO_FROM_WIN32_CODE(ERROR_BAD_LENGTH);
+ return PHP_WIN32_IOUTIL_NORM_FAIL;
}
while (NULL != (pos = wcschr(idx, PHP_WIN32_IOUTIL_FW_SLASHW)) && idx - *buf <= len) {
@@ -521,30 +521,29 @@ PW32IO BOOL php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t
idx = pos++;
}
- shift = PHP_WIN32_IOUTIL_IS_LONG_PATHW(*buf, len) ? PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW : 0;
- if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf + shift, PATHCCH_ALLOW_LONG_PATHS)) {
- *new_len = ret_len;
- return FALSE;
+ if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf, PATHCCH_ALLOW_LONG_PATHS)) {
+ return PHP_WIN32_IOUTIL_NORM_PARTIAL;
}
- canonicalw_len = wcslen(canonicalw);
- if (canonicalw_len + shift != len) {
- if (canonicalw_len > len) {
- *buf = realloc(*buf, (canonicalw_len + 1) * sizeof(wchar_t));
+ ret_len = wcslen(canonicalw);
+ if (ret_len != len) {
+ if (ret_len > len) {
+ wchar_t *tmp = realloc(*buf, (ret_len + 1) * sizeof(wchar_t));
+ if (!tmp) {
+ SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
+ return PHP_WIN32_IOUTIL_NORM_PARTIAL;
+ }
+ *buf = tmp;
}
- memmove(*buf + shift, canonicalw, (canonicalw_len + 1) * sizeof(wchar_t));
- ret_len = canonicalw_len + shift;
+ memmove(*buf, canonicalw, (ret_len + 1) * sizeof(wchar_t));
}
*new_len = ret_len;
- return TRUE;
+ return PHP_WIN32_IOUTIL_NORM_OK;
}/*}}}*/
-static HRESULT MyPathCchCanonicalizeExFallback(wchar_t *pszPathOut, size_t cchPathOut, const wchar_t *pszPathIn, unsigned long dwFlags)
+static HRESULT __stdcall MyPathCchCanonicalizeExFallback(wchar_t *pszPathOut, size_t cchPathOut, const wchar_t *pszPathIn, unsigned long dwFlags)
{/*{{{*/
- cchPathOut = wcslen(pszPathIn);
- memmove(pszPathOut, pszPathIn, (cchPathOut + 1) * sizeof(wchar_t));
-
- return S_OK;
+ return -42;
}/*}}}*/
BOOL php_win32_ioutil_init(void)
diff --git a/win32/ioutil.h b/win32/ioutil.h
index a11c64912e..a97bbd7f56 100644
--- a/win32/ioutil.h
+++ b/win32/ioutil.h
@@ -87,6 +87,11 @@ typedef enum {
PHP_WIN32_IOUTIL_IS_UTF8
} php_win32_ioutil_encoding;
+typedef enum {
+ PHP_WIN32_IOUTIL_NORM_OK,
+ PHP_WIN32_IOUTIL_NORM_PARTIAL,
+ PHP_WIN32_IOUTIL_NORM_FAIL,
+} php_win32_ioutil_normalization_result;
#define PHP_WIN32_IOUTIL_FW_SLASHW L'/'
#define PHP_WIN32_IOUTIL_FW_SLASH '/'
@@ -133,7 +138,7 @@ typedef enum {
} \
} while (0);
-PW32IO BOOL php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len);
+PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len);
#ifdef PHP_EXPORTS
/* This symbols are needed only for the DllMain, but should not be exported
or be available when used with PHP binaries. */
@@ -160,6 +165,11 @@ __forceinline static wchar_t *php_win32_ioutil_conv_any_to_w(const char* in, siz
return NULL;
}
+ /* The return can be ignored here, as the normalization can fail for
+ various reasons not directly related to the operation itself.
+ Partial normalization could still do a better job further. And
+ otherwise, the path might be unchanged which is ok if the path
+ was valid long one. */
(void)php_win32_ioutil_normalize_path_w(&mb, mb_len, &mb_len);
if (PHP_WIN32_IOUTIL_IS_LONG_PATHW(mb, mb_len)) {