mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
rework long path normalization stuf
Simplify, set error codes, ensure 32-bit is ok as well. The canonicalization part is still an issue on win7 as the API is missing there. However a partial improvement is reached there as well thanks to the slash conversion.
This commit is contained in:
parent
ca64223193
commit
4acde210fd
2 changed files with 31 additions and 22 deletions
|
@ -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)
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue