mirror of
https://github.com/ladislav-zezula/StormLib.git
synced 2026-01-15 21:00:32 +01:00
Fixed bug in test program that caused bad cosmetic effects during log print
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -9,7 +9,7 @@
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/StormLib_test",
|
||||
"program": "${workspaceFolder}/build/test/StormLib_test",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
typedef struct _IMAGE_DOS_HEADER
|
||||
{
|
||||
USHORT e_magic;
|
||||
USHORT dummy[0x1B];
|
||||
USHORT dummy[0x1D];
|
||||
DWORD e_lfanew;
|
||||
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ static DWORD UTF8_DecodeSequence(const BYTE * pbString, BYTE BitsMask, size_t cc
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/UTF-8
|
||||
static DWORD UTF8_DecodeCodePoint(const BYTE * pbString, const BYTE * pbStringEnd, DWORD & dwCodePoint, size_t & ccBytesEaten)
|
||||
DWORD UTF8_DecodeCodePoint(const BYTE * pbString, const BYTE * pbStringEnd, DWORD & dwCodePoint, size_t & ccBytesEaten)
|
||||
{
|
||||
// Reset the number of bytes eaten
|
||||
dwCodePoint = SFILE_UTF8_INVALID_CHARACTER;
|
||||
@@ -165,7 +165,7 @@ static size_t UTF8_EncodeSequence(DWORD dwCodePoint, BYTE LeadingByte, DWORD dwF
|
||||
return dwFollowByteCount + 1;
|
||||
}
|
||||
|
||||
static size_t UTF8_EncodeCodePoint(DWORD dwCodePoint, LPBYTE Utf8Buffer)
|
||||
size_t UTF8_EncodeCodePoint(DWORD dwCodePoint, LPBYTE Utf8Buffer)
|
||||
{
|
||||
// 0x00 - 0x7F, 1 byte
|
||||
if(dwCodePoint < 0x80)
|
||||
|
||||
@@ -276,6 +276,12 @@ void StringCat(TCHAR * szTarget, size_t cchTargetMax, const TCHAR * szSource);
|
||||
void StringCat(TCHAR * szTarget, size_t cchTargetMax, const char * szSource);
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// UTF-8 support
|
||||
|
||||
DWORD UTF8_DecodeCodePoint(const BYTE * pbString, const BYTE * pbStringEnd, DWORD & dwCodePoint, size_t & ccBytesEaten);
|
||||
size_t UTF8_EncodeCodePoint(DWORD dwCodePoint, LPBYTE Utf8Buffer);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Encryption and decryption functions
|
||||
|
||||
|
||||
@@ -3866,6 +3866,7 @@ static DWORD TestUtf8Conversions(const BYTE * szTestString, const TCHAR * szList
|
||||
|
||||
static void Test_PlayingSpace()
|
||||
{
|
||||
/*
|
||||
HANDLE hMpq;
|
||||
HANDLE hFile;
|
||||
|
||||
@@ -3881,6 +3882,7 @@ static void Test_PlayingSpace()
|
||||
}
|
||||
SFileCloseArchive(hMpq);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -4178,7 +4180,6 @@ static const TEST_INFO1 Test_OpenMpqs[] =
|
||||
{_T("MPQ_2002_v1_BlockTableCut.MPQ"), NULL, "a9499ab74d939303d8cda7c397c36275", 287}, // Truncated archive
|
||||
{_T("MPQ_2010_v2_HasUserData.s2ma"), NULL, "feff9e2c86db716b6ff5ffc906181200", 52}, // MPQ that actually has user data
|
||||
{_T("MPQ_2014_v1_AttributesOneEntryLess.w3x"), NULL, "90451b7052eb0f1d6f4bf69b2daff7f5", 116}, // Warcraft III map whose "(attributes)" file has (BlockTableSize-1) entries
|
||||
{_T("MPQ_2020_v1_AHF04patch.mix"), NULL, "d3c6aac48bc12813ef5ce4ad113e58bf", 2891}, // MIX file
|
||||
{_T("MPQ_2010_v3_expansion-locale-frFR.MPQ"), NULL, "0c8fc921466f07421a281a05fad08b01", 53}, // MPQ archive v 3.0 (the only one I know)
|
||||
{_T("mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE"), NULL, "10e4dcdbe95b7ad731c563ec6b71bc16", 82}, // Encrypted archive from Starcraft II installer
|
||||
{_T("part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part"),NULL, "d41d8cd98f00b204e9800998ecf8427e", 14263}, // Partial MPQ with compressed hash table
|
||||
@@ -4189,10 +4190,10 @@ static const TEST_INFO1 Test_OpenMpqs[] =
|
||||
{_T("MPQ_2023_v1_Volcanis.scm"), NULL, "522c89ca96d6736427b01f7c80dd626f", 3}, // Map modified with unusual file compression: ZLIB+Huffman
|
||||
{_T("MPQ_2023_v4_UTF8.s2ma"), NULL, "97b7a686650f3307d135e1d1b017a36a", 67}, // Map contaning files with Chinese names (UTF8-encoded)
|
||||
{_T("MPQ_2023_v1_GreenTD.w3x"), NULL, "a8d91fc4e52d7c21ff7feb498c74781a", 2004}, // Corrupt sector checksum table in file #A0
|
||||
|
||||
{_T("MPQ_2023_v4_1F644C5A.SC2Replay"), NULL, "b225828ffbf5037553e6a1290187caab", 17}, // Corrupt patch info of the "(attributes)" file
|
||||
{_T("<Chinese MPQ name>"), NULL, "67faeffd0c0aece205ac8b7282d8ad8e", 4697, &MpqUtf8}, // Chinese name of the MPQ
|
||||
{_T("MPQ_2024_v1_BadUtf8_5.0.2.w3x"), NULL, "be34f9862758f021a1c6c77df3cd4f05", 6393, &LfBad1}, // Bad UTF-8 sequences in file names
|
||||
|
||||
|
||||
// Protected archives
|
||||
{_T("MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x"), NULL, "b900364cc134a51ddeca21a13697c3ca", 79},
|
||||
@@ -4228,9 +4229,10 @@ static const TEST_INFO1 Test_OpenMpqs[] =
|
||||
{_T("MPQ_2024_v1_300TK2.09p.w3x"), NULL, "e442e3d2e7d457b9ba544544013b791f", 32588}, // Fake MPQ User data, fake MPQ header at offset 0x200
|
||||
|
||||
// ASI plugins
|
||||
{_T("MPQ_2020_v1_HS0.1.asi"), NULL, "50cba7460a6e6d270804fb9776a7ec4f", 6022},
|
||||
{_T("MPQ_2022_v1_hs0.8.asi"), NULL, "6a40f733428001805bfe6e107ca9aec1", 11352}, // Items in hash table have platform = 0xFF
|
||||
{_T("MPQ_2022_v1_MoeMoeMod.asi"), NULL, "89b923c7cde06de48815844a5bbb0ec4", 2578},
|
||||
{_T("mix-mpq/AHF04patch.mix"), NULL, "d3c6aac48bc12813ef5ce4ad113e58bf", 2891}, // MIX file
|
||||
{_T("mix-mpq/hs0.1.asi"), NULL, "50cba7460a6e6d270804fb9776a7ec4f", 6022},
|
||||
{_T("mix-mpq/hs0.8.asi"), NULL, "6a40f733428001805bfe6e107ca9aec1", 11352}, // Items in hash table have platform = 0xFF
|
||||
{_T("mix-mpq/MoeMoeMod.asi"), NULL, "89b923c7cde06de48815844a5bbb0ec4", 2578},
|
||||
|
||||
// MPQ modifications from Chinese games
|
||||
{_T("MPx_2013_v1_LongwuOnline.mpk"), NULL, "548f7db88284097f7e94c95a08c5bc24", 469}, // MPK archive from Longwu online
|
||||
@@ -4349,17 +4351,17 @@ static const LPCSTR Test_CreateMpq_Localized[] =
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main
|
||||
|
||||
//#define TEST_COMMAND_LINE
|
||||
//#define TEST_LOCAL_LISTFILE
|
||||
//#define TEST_STREAM_OPERATIONS
|
||||
//#define TEST_MASTER_MIRROR
|
||||
//#define TEST_OPEN_MPQ
|
||||
//#define TEST_REOPEN_MPQ
|
||||
//#define TEST_VERIFY_SIGNATURE
|
||||
//#define TEST_REPLACE_FILE
|
||||
//#define TEST_VERIFY_HASHES
|
||||
#define TEST_COMMAND_LINE
|
||||
#define TEST_LOCAL_LISTFILE
|
||||
#define TEST_STREAM_OPERATIONS
|
||||
#define TEST_MASTER_MIRROR
|
||||
#define TEST_OPEN_MPQ
|
||||
#define TEST_REOPEN_MPQ
|
||||
#define TEST_VERIFY_SIGNATURE
|
||||
#define TEST_REPLACE_FILE
|
||||
#define TEST_VERIFY_HASHES
|
||||
#define TEST_CREATE_MPQS
|
||||
//#define TEST_MISC_MPQS
|
||||
#define TEST_MISC_MPQS
|
||||
|
||||
int _tmain(int argc, TCHAR * argv[])
|
||||
{
|
||||
|
||||
@@ -43,6 +43,58 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
template <typename XCHAR>
|
||||
XCHAR * StringEnd(XCHAR * sz)
|
||||
{
|
||||
while(sz[0] != 0)
|
||||
sz++;
|
||||
return sz;
|
||||
}
|
||||
|
||||
// ANSI version of the function - expects UTF-8 encoding
|
||||
size_t ConsoleLength(const char * ptr, const char * end)
|
||||
{
|
||||
size_t ccBytesEaten;
|
||||
size_t nLength = 0;
|
||||
DWORD dwErrCode;
|
||||
|
||||
while(ptr < end)
|
||||
{
|
||||
DWORD dwCodePoint = 0;
|
||||
|
||||
// Decode a single UTF-8 character
|
||||
dwErrCode = UTF8_DecodeCodePoint((BYTE *)(ptr), (BYTE *)(end), dwCodePoint, ccBytesEaten);
|
||||
if(dwErrCode != ERROR_SUCCESS && dwErrCode != ERROR_NO_UNICODE_TRANSLATION)
|
||||
break;
|
||||
|
||||
// Chinese chars occupy 1 extra char slot on console
|
||||
if(0x5000 <= ptr[0] && ptr[0] <= 0xA000)
|
||||
nLength++;
|
||||
ptr += ccBytesEaten;
|
||||
nLength++;
|
||||
}
|
||||
return nLength;
|
||||
}
|
||||
|
||||
#ifdef TEST_PLATFORM_WINDOWS
|
||||
size_t ConsoleLength(const wchar_t * ptr, const wchar_t * end)
|
||||
{
|
||||
size_t nLength = 0;
|
||||
|
||||
while(ptr < end)
|
||||
{
|
||||
DWORD dwCodePoint = ptr[0];
|
||||
|
||||
// Chinese chars occupy more space
|
||||
if(0x5000 <= dwCodePoint && dwCodePoint <= 0xA000)
|
||||
nLength++;
|
||||
ptr += 1;
|
||||
nLength++;
|
||||
}
|
||||
return nLength;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline DWORD TestInterlockedIncrement(DWORD * PtrValue)
|
||||
{
|
||||
#ifdef TEST_PLATFORM_WINDOWS
|
||||
@@ -63,7 +115,7 @@ inline DWORD Test_GetLastError()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef STORMLIB_WINDOWS
|
||||
#ifdef TEST_PLATFORM_WINDOWS
|
||||
wchar_t * CopyFormatCharacter(wchar_t * szBuffer, const wchar_t *& szFormat)
|
||||
{
|
||||
static const wchar_t * szStringFormat = L"%s";
|
||||
@@ -92,7 +144,7 @@ wchar_t * CopyFormatCharacter(wchar_t * szBuffer, const wchar_t *& szFormat)
|
||||
*szBuffer++ = *szFormat++;
|
||||
return szBuffer;
|
||||
}
|
||||
#endif // STORMLIB_WINDOWS
|
||||
#endif // TEST_PLATFORM_WINDOWS
|
||||
|
||||
char * CopyFormatCharacter(char * szBuffer, const char *& szFormat)
|
||||
{
|
||||
@@ -186,9 +238,7 @@ class TLogHelper
|
||||
#ifdef TEST_PLATFORM_WINDOWS
|
||||
InitializeCriticalSection(&Locker);
|
||||
TickCount = GetTickCount();
|
||||
#endif
|
||||
|
||||
#ifdef STORMLIB_WINDOWS
|
||||
SetConsoleOutputCP(CP_UTF8); // Set the UTF-8 code page to handle national-specific names
|
||||
SetConsoleCP(CP_UTF8);
|
||||
#endif
|
||||
@@ -282,7 +332,7 @@ class TLogHelper
|
||||
va_start(argList, format);
|
||||
int nLength = 0;
|
||||
|
||||
#ifdef STORMLIB_WINDOWS
|
||||
#ifdef TEST_PLATFORM_WINDOWS
|
||||
char * szBuffer;
|
||||
int ccBuffer = 0x1000;
|
||||
|
||||
@@ -303,7 +353,7 @@ class TLogHelper
|
||||
return nLength;
|
||||
}
|
||||
|
||||
#ifdef STORMLIB_WINDOWS
|
||||
#ifdef TEST_PLATFORM_WINDOWS
|
||||
int printf_console(const wchar_t * format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
@@ -330,18 +380,19 @@ class TLogHelper
|
||||
template <typename XCHAR>
|
||||
DWORD PrintWithClreol(const XCHAR * szFormat, va_list argList, bool bPrintLastError, bool bPrintEndOfLine)
|
||||
{
|
||||
char * szBufferPtr;
|
||||
char * szBufferEnd;
|
||||
XCHAR * szBufferPtr;
|
||||
XCHAR * szBufferEnd;
|
||||
size_t nLength = 0;
|
||||
DWORD dwErrCode = Test_GetLastError();
|
||||
XCHAR szMessage[0x200];
|
||||
char szBuffer[0x200];
|
||||
XCHAR szPercentS[] = {'%', 's', 0};
|
||||
XCHAR szMessage[0x200] = {0};
|
||||
XCHAR szBuffer[0x200] = {0};
|
||||
bool bPrintPrefix = TEST_PRINT_PREFIX;
|
||||
|
||||
// Always start the buffer with '\r'
|
||||
szBufferEnd = szBuffer + _countof(szBuffer);
|
||||
szBufferPtr = szBuffer;
|
||||
*szBufferPtr++ = '\r';
|
||||
szBufferPtr = szBuffer + 1;
|
||||
szBuffer[0] = '\r';
|
||||
|
||||
// Print the prefix, if needed
|
||||
if(szMainTitle != NULL && bPrintPrefix)
|
||||
@@ -356,45 +407,41 @@ class TLogHelper
|
||||
// Construct the message
|
||||
TestStrPrintfV(szMessage, _countof(szMessage), szFormat, argList);
|
||||
StringCopy(szBufferPtr, (szBufferEnd - szBufferPtr), szMessage);
|
||||
szBufferPtr = szBufferPtr + strlen(szBufferPtr);
|
||||
szBufferPtr = StringEnd(szBufferPtr);
|
||||
|
||||
// Append the last error
|
||||
if(bPrintLastError)
|
||||
{
|
||||
nLength = TestStrPrintf(szBufferPtr, (szBufferEnd - szBufferPtr), " (error code: %u)", dwErrCode);
|
||||
XCHAR szErrMsg[] = {' ', '(', 'e', 'r', 'r', 'o', 'r', ' ', 'c', 'o', 'd', 'e', ':', ' ', '%', 'u', ')', 0, 0};
|
||||
nLength = TestStrPrintf(szBufferPtr, (szBufferEnd - szBufferPtr), szErrMsg, dwErrCode);
|
||||
szBufferPtr += nLength;
|
||||
}
|
||||
|
||||
// Shall we pad the string?
|
||||
if((nLength = (szBufferPtr - szBuffer)) < nPrevPrinted)
|
||||
{
|
||||
size_t nPadding = nPrevPrinted - nLength;
|
||||
|
||||
if((size_t)(nLength + nPadding) > (size_t)(szBufferEnd - szBufferPtr))
|
||||
nPadding = (szBufferEnd - szBufferPtr);
|
||||
|
||||
memset(szBufferPtr, ' ', nPadding);
|
||||
szBufferPtr += nPadding;
|
||||
}
|
||||
// Pad the string with zeros, if needed
|
||||
while(szBufferPtr < (szBuffer + nPrevPrinted))
|
||||
*szBufferPtr++ = ' ';
|
||||
|
||||
// Remember how much did we print
|
||||
nPrevPrinted = (szBufferPtr - szBuffer);
|
||||
nPrevPrinted = ConsoleLength(szBuffer, szBufferPtr);
|
||||
|
||||
// Shall we add new line?
|
||||
if((bPrintEndOfLine) && (szBufferPtr < szBufferEnd))
|
||||
*szBufferPtr++ = '\n';
|
||||
// Always add one extra space *AFTER* calculating length
|
||||
if(szBufferPtr < szBufferEnd)
|
||||
*szBufferPtr++ = ' ';
|
||||
*szBufferPtr = 0;
|
||||
|
||||
// Remember if we printed a message
|
||||
// Print the message to the console
|
||||
printf_console(szPercentS, szBuffer);
|
||||
nMessageCounter++;
|
||||
|
||||
// If we shall print the newline, do it
|
||||
if(bPrintEndOfLine)
|
||||
{
|
||||
bMessagePrinted = true;
|
||||
nPrevPrinted = 0;
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Finally print the message
|
||||
printf_console("%s", szBuffer);
|
||||
nMessageCounter++;
|
||||
return dwErrCode;
|
||||
}
|
||||
|
||||
@@ -614,7 +661,7 @@ class TLogHelper
|
||||
const TCHAR * szSubTitle1; // Title of the text (can be name of the tested file)
|
||||
const TCHAR * szSubTitle2; // Title of the text (can be name of the tested file)
|
||||
size_t nMessageCounter;
|
||||
size_t nPrevPrinted; // Length of the previously printed message
|
||||
size_t nPrevPrinted;
|
||||
time_t dwPrevTickCount;
|
||||
bool bMessagePrinted;
|
||||
};
|
||||
|
||||
@@ -55,7 +55,6 @@ TestReadingMpq: Warning: CRC32 error on (listfile)
|
||||
TestReadingMpq: Warning: CRC32 error on (listfile)
|
||||
TestReadingMpq: Warning: CRC32 error on File00000003.xxx
|
||||
TestReadingMpq (MPQ_2014_v1_AttributesOneEntryLess.w3x) succeeded.
|
||||
TestReadingMpq (MPQ_2020_v1_AHF04patch.mix) succeeded.
|
||||
TestReadingMpq (MPQ_2010_v3_expansion-locale-frFR.MPQ) succeeded.
|
||||
TestReadingMpq (mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE) succeeded.
|
||||
TestReadingMpq (part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part) succeeded.
|
||||
@@ -69,7 +68,7 @@ TestReadingMpq (MPQ_2023_v4_UTF8.s2ma) succeeded.
|
||||
TestReadingMpq (MPQ_2023_v1_GreenTD.w3x) succeeded.
|
||||
TestReadingMpq (MPQ_2023_v4_1F644C5A.SC2Replay) succeeded.
|
||||
TestReadingMpq (<Chinese MPQ name>) succeeded.
|
||||
TestReadingMpq (MPQ_2024_v1_BadUtf8_5.0.2.w3x) succeeded.
|
||||
TestReadingMpq (MPQ_2024_v1_BadUtf8_5.0.2.w3x) succeeded. ... ..
|
||||
TestReadingMpq (MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x) succeeded.
|
||||
TestReadingMpq (MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x) succeeded.
|
||||
TestReadingMpq (MPQ_2002_v1_ProtectedMap_Spazzler.w3x) succeeded.
|
||||
@@ -101,9 +100,10 @@ TestReadingMpq (MPQ_2022_v1_Sniper.scx) succeeded.
|
||||
TestReadingMpq (MPQ_2022_v1_OcOc_Bound_2.scx) succeeded.
|
||||
TestReadingMpq (MPQ_2023_v1_Lusin2Rpg1.28.w3x) succeeded.
|
||||
TestReadingMpq (MPQ_2024_v1_300TK2.09p.w3x) succeeded.
|
||||
TestReadingMpq (MPQ_2020_v1_HS0.1.asi) succeeded.
|
||||
TestReadingMpq (MPQ_2022_v1_hs0.8.asi) succeeded.
|
||||
TestReadingMpq (MPQ_2022_v1_MoeMoeMod.asi) succeeded.
|
||||
TestReadingMpq (mix-mpq/AHF04patch.mix) succeeded.
|
||||
TestReadingMpq (mix-mpq/hs0.1.asi) succeeded.
|
||||
TestReadingMpq (mix-mpq/hs0.8.asi) succeeded.
|
||||
TestReadingMpq (mix-mpq/MoeMoeMod.asi) succeeded.
|
||||
TestReadingMpq (MPx_2013_v1_LongwuOnline.mpk) succeeded.
|
||||
TestReadingMpq (MPx_2013_v1_WarOfTheImmortals.sqp) succeeded.
|
||||
TestReadingMpq (MPx_2022_v1_Music.mpk) succeeded.
|
||||
@@ -155,12 +155,12 @@ TestModifyMpq (MPQ_2023_v1_StarcraftMap.scm) succeeded.
|
||||
TestVerifyHash succeeded.
|
||||
CreateNewMpq (StormLibTest_EmptyMpq_v2.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_EmptyMpq_v4.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_Český.mpq) succeeded. ..
|
||||
CreateNewMpq (StormLibTest_Русский.mpq) succeeded. ...
|
||||
CreateNewMpq (StormLibTest_Český.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_Русский.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_ελληνικά.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_日本語.mpq) succeeded. ...
|
||||
CreateNewMpq (StormLibTest_简体中文.mpq) succeeded....
|
||||
CreateNewMpq (StormLibTest_الععربية.mpq) succeeded....
|
||||
CreateNewMpq (StormLibTest_日本語.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_简体中文.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_الععربية.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_NonStdNames.mpq) succeeded.
|
||||
CreateNewMpq (StormLibTest_MpqEditorTest.mpq) succeeded.
|
||||
TestCreateGaps (StormLibTest_GapsTest.mpq) succeeded.
|
||||
|
||||
Reference in New Issue
Block a user