[builds/windows] Revert back to `CreateFileA` only.

Calling `CreateFileW` without making sure that the patname is really
`wchar_t` is a bad idea and can lead to unpredictable overreads. For
Windows CE, we impelemnt the missing API.

Fixes #1098 and !76 again.

* builds/windows/ftsystem.c (FT_Stream_Open): Call `CreateFileA`.
[_WIN32_WCE] (CreateFileA, FileSizeEx): Implement missing interfaces.
This commit is contained in:
Alexei Podtelezhnikov 2021-09-21 23:14:42 -04:00
parent 892e7eadc9
commit 93866bec77
1 changed files with 60 additions and 25 deletions

View File

@ -196,6 +196,61 @@
}
#ifdef _WIN32_WCE
FT_LOCAL_DEF( HANDLE )
CreateFileA( LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile )
{
int len;
LPWSTR lpFileNameW;
/* allocate memory space for converted path name */
len = MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
lpFileName, -1, NULL, 0 );
lpFileNameW = (LPWSTR)_alloca( len * sizeof ( WCHAR ) );
if ( !len || !lpFileNameW )
{
FT_ERROR(( "FT_Stream_Open: cannot convert file name to LPWSTR\n" ));
return INVALID_HANDLE_VALUE;
}
/* now it is safe to do the translation */
MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
lpFileName, -1, lpFileNameW, len );
/* open the file */
return CreateFileW( lpFileNameW, dwDesiredAccess, dwShareMode,
lpSecurityAttributes, dwCreationDisposition,
dwFlagsAndAttributes, hTemplateFile );
}
FT_LOCAL_DEF( BOOL )
GetFileSizeEx( HANDLE hFile,
PLARGE_INTEGER lpFileSize )
{
lpFileSize->u.LowPart = GetFileSize( hFile,
(DWORD *)&lpFileSize->u.HighPart );
if ( lpFileSize->u.LowPart == INVALID_FILE_SIZE &&
GetLastError() != NO_ERROR )
return FALSE;
else
return TRUE;
}
#endif /* _WIN32_WCE */
/* documentation is in ftobjs.h */
FT_BASE_DEF( FT_Error )
@ -211,36 +266,16 @@
return FT_THROW( Invalid_Stream_Handle );
/* open the file */
file = CreateFile( (LPCTSTR)filepathname, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
file = CreateFileA( (LPCSTR)filepathname, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
if ( file == INVALID_HANDLE_VALUE )
{
/* fall back on the alernative interface */
#ifdef UNICODE
file = CreateFileA( (LPCSTR)filepathname, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
#else
file = CreateFileW( (LPCWSTR)filepathname, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
#endif
if ( file == INVALID_HANDLE_VALUE )
{
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not open `%s'\n", filepathname ));
return FT_THROW( Cannot_Open_Resource );
}
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not open `%s'\n", filepathname ));
return FT_THROW( Cannot_Open_Resource );
}
#if defined _WIN32_WCE || defined _WIN32_WINDOWS || \
(defined _WIN32_WINNT && _WIN32_WINNT <= 0x0400)
/* Use GetFileSize() for legacy Windows */
size.u.LowPart = GetFileSize( file, (DWORD *)&size.u.HighPart );
if ( size.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR )
#else
/* Use GetFileSizeEx() for modern Windows */
if ( GetFileSizeEx( file, &size ) == FALSE )
#endif
{
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " could not retrieve size of file `%s'\n", filepathname ));