diff options
author | Ladislav Zezula <zezula@volny.cz> | 2020-08-26 10:17:05 +0200 |
---|---|---|
committer | Ladislav Zezula <zezula@volny.cz> | 2020-08-26 10:17:05 +0200 |
commit | f438d59c5c10c9d2308ac1bfaff8da54bdbb8c4f (patch) | |
tree | a8e531af5191cbd428a538805392b62002de8124 | |
parent | c20d117942a324b97ee5e326f6630ecf0f6d5a23 (diff) |
* Removed sprintf as source of incompatibilities
* Fixed bug
-rw-r--r-- | src/FileStream.cpp | 28 | ||||
-rw-r--r-- | src/SBaseCommon.cpp | 28 | ||||
-rw-r--r-- | src/SFileFindFile.cpp | 2 | ||||
-rw-r--r-- | src/SFileGetFileInfo.cpp | 5 | ||||
-rw-r--r-- | src/StormCommon.h | 40 | ||||
-rw-r--r-- | test/StormTest.cpp | 13 |
6 files changed, 98 insertions, 18 deletions
diff --git a/src/FileStream.cpp b/src/FileStream.cpp index a492e66..a462690 100644 --- a/src/FileStream.cpp +++ b/src/FileStream.cpp @@ -53,13 +53,29 @@ static DWORD StringToInt(const char * szString) while('0' <= szString[0] && szString[0] <= '9')
{
- dwValue = (dwValue * 10) + (szString[0] - '9');
+ dwValue = (dwValue * 10) + (szString[0] - '0');
szString++;
}
return dwValue;
}
+static void CreateNameWithSuffix(LPTSTR szBuffer, size_t cchMaxChars, LPCTSTR szName, unsigned int nValue)
+{
+ LPTSTR szBufferEnd = szBuffer + cchMaxChars - 1;
+
+ // Copy the name
+ while(szBuffer < szBufferEnd && szName[0] != 0)
+ *szBuffer++ = *szName++;
+
+ // Append "."
+ if(szBuffer < szBufferEnd)
+ *szBuffer++ = '.';
+
+ // Append the number
+ IntToString(szBuffer, szBufferEnd - szBuffer + 1, nValue);
+}
+
//-----------------------------------------------------------------------------
// Dummy init function
@@ -800,7 +816,7 @@ static bool BaseHttp_Read( {
// Add range request to the HTTP headers
// http://www.clevercomponents.com/articles/article015/resuming.asp
- _stprintf(szRangeRequest, _T("Range: bytes=%u-%u"), (unsigned int)dwStartOffset, (unsigned int)dwEndOffset);
+ wsprintf(szRangeRequest, _T("Range: bytes=%u-%u"), (unsigned int)dwStartOffset, (unsigned int)dwEndOffset);
HttpAddRequestHeaders(hRequest, szRangeRequest, 0xFFFFFFFF, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
// Send the request to the server
@@ -1738,7 +1754,7 @@ static void PartStream_Close(TBlockStream * pStream) // Make sure that the header is properly BSWAPed
BSWAP_ARRAY32_UNSIGNED(&PartHeader, sizeof(PART_FILE_HEADER));
- sprintf(PartHeader.GameBuildNumber, "%u", (unsigned int)pStream->BuildNumber);
+ IntToString(PartHeader.GameBuildNumber, _countof(PartHeader.GameBuildNumber), pStream->BuildNumber);
// Write the part header
pStream->BaseWrite(pStream, &ByteOffset, &PartHeader, sizeof(PART_FILE_HEADER));
@@ -2323,7 +2339,7 @@ static TFileStream * Block4Stream_Open(const TCHAR * szFileName, DWORD dwStreamF for(int nSuffix = 0; nSuffix < 30; nSuffix++)
{
// Open the n-th file
- _stprintf(szNameBuff, _T("%s.%u"), pStream->szFileName, nSuffix);
+ CreateNameWithSuffix(szNameBuff, nNameLength + 4, pStream->szFileName, nSuffix);
if(!pStream->BaseOpen(pStream, szNameBuff, dwBaseFlags))
break;
@@ -2887,10 +2903,10 @@ void FileStream_Close(TFileStream * pStream) FileStream_Close(pStream->pMaster);
pStream->pMaster = NULL;
- // Close the stream provider ...
+ // Close the stream provider
if(pStream->StreamClose != NULL)
pStream->StreamClose(pStream);
-
+
// ... or close base stream, if any
else if(pStream->BaseClose != NULL)
pStream->BaseClose(pStream);
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index 61e7bdb..fc80dee 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -95,11 +95,13 @@ unsigned char AsciiToUpperTable_Slash[256] = //-----------------------------------------------------------------------------
// Safe string functions (for ANSI builds)
-void StringCopy(char * szTarget, size_t cchTarget, const char * szSource)
+char * StringCopy(char * szTarget, size_t cchTarget, const char * szSource)
{
+ size_t cchSource = 0;
+
if(cchTarget > 0)
{
- size_t cchSource = strlen(szSource);
+ cchSource = strlen(szSource);
if(cchSource >= cchTarget)
cchSource = cchTarget - 1;
@@ -107,6 +109,8 @@ void StringCopy(char * szTarget, size_t cchTarget, const char * szSource) memcpy(szTarget, szSource, cchSource);
szTarget[cchSource] = 0;
}
+
+ return szTarget + cchSource;
}
void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource)
@@ -121,6 +125,26 @@ void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource) }
}
+void StringCreatePseudoFileName(char * szBuffer, size_t cchMaxChars, unsigned int nIndex, const char * szExtension)
+{
+ char * szBufferEnd = szBuffer + cchMaxChars;
+
+ // "File"
+ szBuffer = StringCopy(szBuffer, (szBufferEnd - szBuffer), "File");
+
+ // Number
+ szBuffer = IntToString(szBuffer, szBufferEnd - szBuffer + 1, nIndex, 8);
+
+ // Dot
+ if(szBuffer < szBufferEnd)
+ *szBuffer++ = '.';
+
+ // Extension
+ while(szExtension[0] == '.')
+ szExtension++;
+ StringCopy(szBuffer, (szBufferEnd - szBuffer), szExtension);
+}
+
//-----------------------------------------------------------------------------
// Utility functions (UNICODE) only exist in the ANSI version of the library
// In ANSI builds, TCHAR = char, so we don't need these functions implemented
diff --git a/src/SFileFindFile.cpp b/src/SFileFindFile.cpp index 30be19a..7e8502b 100644 --- a/src/SFileFindFile.cpp +++ b/src/SFileFindFile.cpp @@ -244,7 +244,7 @@ static bool DoMPQSearch_FileEntry( if(szFileName == NULL)
{
// Open the file by its pseudo-name.
- sprintf(szNameBuff, "File%08u.xxx", (unsigned int)dwBlockIndex);
+ StringCreatePseudoFileName(szNameBuff, _countof(szNameBuff), dwBlockIndex, "xxx");
if(SFileOpenFileEx((HANDLE)hs->ha, szNameBuff, SFILE_OPEN_BASE_FILE, &hFile))
{
SFileGetFileName(hFile, szNameBuff);
diff --git a/src/SFileGetFileInfo.cpp b/src/SFileGetFileInfo.cpp index 8d57f7a..c57b3b7 100644 --- a/src/SFileGetFileInfo.cpp +++ b/src/SFileGetFileInfo.cpp @@ -926,6 +926,7 @@ static int CreatePseudoFileName(HANDLE hFile, TFileEntry * pFileEntry, char * sz DWORD FirstBytes[2] = {0, 0}; // The first 4 bytes of the file
DWORD dwBytesRead = 0;
DWORD dwFilePos; // Saved file position
+ char szPseudoName[20];
// Read the first 2 DWORDs bytes from the file
dwFilePos = SFileSetFilePointer(hFile, 0, NULL, FILE_CURRENT);
@@ -944,10 +945,8 @@ static int CreatePseudoFileName(HANDLE hFile, TFileEntry * pFileEntry, char * sz if((FirstBytes[0] & data2ext[i].dwOffset00Mask) == data2ext[i].dwOffset00Data &&
(FirstBytes[1] & data2ext[i].dwOffset04Mask) == data2ext[i].dwOffset04Data)
{
- char szPseudoName[20] = "";
-
// Format the pseudo-name
- sprintf(szPseudoName, "File%08u.%s", (unsigned int)(pFileEntry - hf->ha->pFileTable), data2ext[i].szExt);
+ StringCreatePseudoFileName(szPseudoName, _countof(szPseudoName), (unsigned int)(pFileEntry - hf->ha->pFileTable), data2ext[i].szExt);
// Save the pseudo-name in the file entry as well
AllocateFileName(hf->ha, pFileEntry, szPseudoName);
diff --git a/src/StormCommon.h b/src/StormCommon.h index de88357..f622e02 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -133,8 +133,46 @@ extern unsigned char AsciiToUpperTable[256]; //-----------------------------------------------------------------------------
// Safe string functions
-void StringCopy(char * szTarget, size_t cchTarget, const char * szSource);
+template <typename XCHAR, typename XINT>
+XCHAR * IntToString(XCHAR * szBuffer, size_t cchMaxChars, XINT nValue, size_t nDigitCount = 0)
+{
+ XCHAR * szBufferEnd = szBuffer + cchMaxChars - 1;
+ XCHAR szNumberRev[0x20];
+ size_t nLength = 0;
+
+ // Always put the first digit
+ szNumberRev[nLength++] = (nValue % 10) + '0';
+ nValue /= 10;
+
+ // Continue as long as we have non-zero
+ while(nValue != 0)
+ {
+ szNumberRev[nLength++] = (nValue % 10) + '0';
+ nValue /= 10;
+ }
+
+ // Fill zeros, if needed
+ while(szBuffer < szBufferEnd && nLength < nDigitCount)
+ {
+ *szBuffer++ = '0';
+ nDigitCount--;
+ }
+
+ // Fill the buffer
+ while(szBuffer < szBufferEnd && nLength > 0)
+ {
+ nLength--;
+ *szBuffer++ = szNumberRev[nLength];
+ }
+
+ // Terminate the number with zeros
+ szBuffer[0] = 0;
+ return szBuffer;
+}
+
+char * StringCopy(char * szTarget, size_t cchTarget, const char * szSource);
void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource);
+void StringCreatePseudoFileName(char * szBuffer, size_t cchMaxChars, unsigned int nIndex, const char * szExtension);
#ifdef _UNICODE
void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource);
diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 9766fd0..6732ed0 100644 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -1559,8 +1559,8 @@ static TFileData * LoadMpqFile(TLogHelper * pLogger, HANDLE hMpq, LPCSTR szFileN pLogger->PrintProgress("Loading file %s ...", GetShortPlainName(szFileName));
#if defined(_MSC_VER) && defined(_DEBUG)
- if(!_stricmp(szFileName, "File00000733.wav"))
- __debugbreak();
+// if(!_stricmp(szFileName, "File00000733.wav"))
+// __debugbreak();
#endif
// Make sure that we open the proper locale file
@@ -4409,6 +4409,9 @@ int _tmain(int argc, TCHAR * argv[]) printf("==== Test Suite for StormLib version %s ====\n", STORMLIB_VERSION_STRING);
nError = InitializeMpqDirectory(argv, argc);
+ HANDLE hMpq = NULL;
+ SFileOpenArchive(_T("e:\\Multimedia\\MPQs\\2010 - Starcraft II\\25092\\Updates\\enGB\\s2-update-enGB-24540.MPQ"), 0, 0, &hMpq);
+
// Not a test, but rather a tool for creating links to duplicated files
// if(nError == ERROR_SUCCESS)
// nError = FindFilePairs(ForEachFile_CreateArchiveLink, "2004 - WoW\\06080", "2004 - WoW\\06299");
@@ -4656,8 +4659,8 @@ int _tmain(int argc, TCHAR * argv[]) */
// Test on an archive that has two fake headers before the real one
if (nError == ERROR_SUCCESS)
- nError = TestOpenArchive_Corrupt(_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod"));
-/*
+ nError = TestOpenArchive(_T("MPQ_2020_v4_FakeMpqHeaders.SC2Mod"));
+
// Open a patched archive
if(nError == ERROR_SUCCESS)
nError = TestOpenArchive_Patched(PatchList_StarCraft, "music\\terran1.wav", 0);
@@ -4852,7 +4855,7 @@ int _tmain(int argc, TCHAR * argv[]) // Test replacing a file with zero size file
if(nError == ERROR_SUCCESS)
nError = TestModifyArchive_ReplaceFile(_T("MPQ_2014_v4_Base.StormReplay"), _T("AddFile-replay.message.events"));
-*/
+
#ifdef _MSC_VER
_CrtDumpMemoryLeaks();
#endif // _MSC_VER
|