Commit 12a134fd authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

kernel32: Fixed buffer overflow in GetShortPathNameW.

parent 47319a00
......@@ -443,7 +443,7 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
WCHAR *tmpshortpath;
LPCWSTR p;
DWORD sp = 0, lp = 0;
DWORD tmplen;
DWORD tmplen, buf_len;
WIN32_FIND_DATAW wfd;
HANDLE goit;
......@@ -462,7 +462,8 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
/* code below only removes characters from string, never adds, so this is
* the largest buffer that tmpshortpath will need to have */
tmpshortpath = HeapAlloc(GetProcessHeap(), 0, (strlenW(longpath) + 1) * sizeof(WCHAR));
buf_len = strlenW(longpath) + 1;
tmpshortpath = HeapAlloc(GetProcessHeap(), 0, buf_len * sizeof(WCHAR));
if (!tmpshortpath)
{
SetLastError(ERROR_OUTOFMEMORY);
......@@ -524,6 +525,23 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
goit = FindFirstFileW(tmpshortpath, &wfd);
if (goit == INVALID_HANDLE_VALUE) goto notfound;
FindClose(goit);
/* In rare cases (like "a.abcd") short path may be longer than original path.
* Make sure we have enough space in temp buffer. */
if (wfd.cAlternateFileName && tmplen < strlenW(wfd.cAlternateFileName))
{
WCHAR *new_buf;
buf_len += strlenW(wfd.cAlternateFileName) - tmplen;
new_buf = HeapReAlloc(GetProcessHeap(), 0, tmpshortpath, buf_len * sizeof(WCHAR));
if(!new_buf)
{
HeapFree(GetProcessHeap(), 0, tmpshortpath);
SetLastError(ERROR_OUTOFMEMORY);
return 0;
}
tmpshortpath = new_buf;
}
strcpyW(tmpshortpath + sp, wfd.cAlternateFileName[0] ? wfd.cAlternateFileName : wfd.cFileName);
sp += strlenW(tmpshortpath + sp);
lp += tmplen;
......
......@@ -1350,7 +1350,8 @@ static void test_GetShortPathNameW(void)
static const WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
static const WCHAR name[] = { 't', 'e', 's', 't', 0 };
static const WCHAR backSlash[] = { '\\', 0 };
WCHAR path[MAX_PATH], tmppath[MAX_PATH];
static const WCHAR a_bcdeW[] = {'a','.','b','c','d','e',0};
WCHAR path[MAX_PATH], tmppath[MAX_PATH], *ptr;
WCHAR short_path[MAX_PATH];
DWORD length;
HANDLE file;
......@@ -1387,7 +1388,7 @@ static void test_GetShortPathNameW(void)
length = GetShortPathNameW( path, short_path, 0 );
ok( length, "GetShortPathNameW returned 0.\n" );
ret = GetShortPathNameW( path, short_path, length );
ok( ret, "GetShortPathNameW returned 0.\n" );
ok( ret && ret == length-1, "GetShortPathNameW returned 0.\n" );
lstrcatW( short_path, name );
......@@ -1399,11 +1400,24 @@ static void test_GetShortPathNameW(void)
file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
/* End test */
CloseHandle( file );
ret = DeleteFileW( short_path );
ok( ret, "Cannot delete file.\n" );
ptr = path + lstrlenW(path);
lstrcpyW( ptr, a_bcdeW);
file = CreateFileW( path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
CloseHandle( file );
length = GetShortPathNameW( path, short_path, sizeof(short_path)/sizeof(*short_path) );
ok( length, "GetShortPathNameW failed: %u.\n", GetLastError() );
ret = DeleteFileW( path );
ok( ret, "Cannot delete file.\n" );
*ptr = 0;
/* End test */
ret = RemoveDirectoryW( path );
ok( ret, "Cannot delete directory.\n" );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment