From be21f80f42a665fcd4a4a9bbdb2dedca83beb9a2 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 30 Mar 2021 10:53:25 +0100 Subject: [PATCH] Fix `SBmpLoadImage` size allocation SBmpLoadImage tried to get the size of the rest of the file incorrectly by subtracting the current file position from the total size. This was incorrect because file positions do not always begin at 0. The only semi-portable way to get a size from file positions is to subtract two file positions. --- 3rdParty/Storm/Source/storm.h | 2 +- SourceX/storm/storm.cpp | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/3rdParty/Storm/Source/storm.h b/3rdParty/Storm/Source/storm.h index 2171d6c56..3b6c29ec8 100644 --- a/3rdParty/Storm/Source/storm.h +++ b/3rdParty/Storm/Source/storm.h @@ -346,7 +346,7 @@ bool SNetRegisterEventHandler(event_type, SEVTHANDLER); BOOLEAN SNetSetBasePlayer(int); int SNetInitializeProvider(unsigned long, struct _SNETPROGRAMDATA *, struct _SNETPLAYERDATA *, struct _SNETUIDATA *, struct _SNETVERSIONDATA *); int SNetGetProviderCaps(struct _SNETCAPS *); -int SFileSetFilePointer(HANDLE, int, HANDLE, int); +int SFileSetFilePointer(HANDLE, int, int*, int); BOOL SFileEnableDirectAccess(BOOL enable); #if defined(__GNUC__) || defined(__cplusplus) diff --git a/SourceX/storm/storm.cpp b/SourceX/storm/storm.cpp index 3dad95857..af54b51e7 100644 --- a/SourceX/storm/storm.cpp +++ b/SourceX/storm/storm.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "all.h" @@ -126,6 +127,23 @@ BOOL SFileOpenFile(const char *filename, HANDLE *phFile) return result; } +static std::uint64_t GetFilePointer(HANDLE hFile) +{ + // We use `SFileSetFilePointer` with offset 0 to get the current position + // because there is no `SFileGetFilePointer`. + int high = 0; + const std::uint32_t low = SFileSetFilePointer(hFile, 0, &high, DVL_FILE_CURRENT); + return (static_cast(high) << 32) | low; +} + +static std::uint64_t SetFilePointer(HANDLE hFile, std::int64_t offset, int whence) +{ + int high = static_cast(offset) >> 32; + int low = static_cast(offset); + low = SFileSetFilePointer(hFile, low, &high, whence); + return (static_cast(high) << 32) | low; +} + BOOL SBmpLoadImage(const char *pszFileName, SDL_Color *pPalette, BYTE *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *dwHeight, DWORD *pdwBpp) { HANDLE hFile; @@ -192,10 +210,11 @@ BOOL SBmpLoadImage(const char *pszFileName, SDL_Color *pPalette, BYTE *pBuffer, *pdwBpp = pcxhdr.BitsPerPixel; if (!pBuffer) { - SFileSetFilePointer(hFile, 0, 0, DVL_FILE_END); + SFileSetFilePointer(hFile, 0, NULL, DVL_FILE_END); fileBuffer = NULL; } else { - size = SFileGetFileSize(hFile, 0) - SFileSetFilePointer(hFile, 0, 0, DVL_FILE_CURRENT); + const auto pos = GetFilePointer(hFile); + size = SetFilePointer(hFile, 0, DVL_FILE_END) - SetFilePointer(hFile, pos, DVL_FILE_BEGIN); fileBuffer = (BYTE *)malloc(size); } @@ -228,7 +247,7 @@ BOOL SBmpLoadImage(const char *pszFileName, SDL_Color *pPalette, BYTE *pBuffer, } if (pPalette && pcxhdr.BitsPerPixel == 8) { - SFileSetFilePointer(hFile, -768, 0, 1); + SFileSetFilePointer(hFile, -768, NULL, DVL_FILE_CURRENT); SFileReadFile(hFile, paldata, 768, 0, 0); for (int i = 0; i < 256; i++) { pPalette[i].r = paldata[i][0];