Skip to content

Commit a9373ee

Browse files
committed
Fix crash in SUM mode when a file name contains % characters (e.g. %S)
1 parent 8f9ba6e commit a9373ee

File tree

1 file changed

+59
-17
lines changed

1 file changed

+59
-17
lines changed

DirHash.cpp

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -249,26 +249,62 @@ std::wstring FormatString(LPCTSTR fmt, ...)
249249
return ret;
250250
}
251251

252+
void ReplaceAll(std::wstring& str, const std::wstring& from, const std::wstring& to) {
253+
if (from.length())
254+
{
255+
size_t start_pos = 0;
256+
while ((start_pos = str.find(from, start_pos)) != std::wstring::npos) {
257+
str.replace(start_pos, from.length(), to);
258+
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
259+
}
260+
}
261+
}
262+
263+
void SanitizeString(std::wstring& str)
264+
{
265+
ReplaceAll(str, L"%", L"%%");
266+
}
267+
268+
void ShowMessage(WORD attributes, LPCTSTR szMsg, va_list args)
269+
{
270+
SetConsoleTextAttribute(g_hConsole, attributes);
271+
_vtprintf(szMsg, args);
272+
SetConsoleTextAttribute(g_hConsole, g_wCurrentAttributes);
273+
}
274+
275+
void ShowMessageDirect(WORD attributes, LPCTSTR szMsg)
276+
{
277+
SetConsoleTextAttribute(g_hConsole, attributes);
278+
_tprintf(szMsg);
279+
SetConsoleTextAttribute(g_hConsole, g_wCurrentAttributes);
280+
}
281+
252282
void ShowError(LPCTSTR szMsg, ...)
253283
{
254284
va_list args;
255285
va_start(args, szMsg);
256-
SetConsoleTextAttribute(g_hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
257-
_vtprintf(szMsg, args);
258-
SetConsoleTextAttribute(g_hConsole, g_wCurrentAttributes);
286+
ShowMessage (FOREGROUND_RED | FOREGROUND_INTENSITY, szMsg, args);
259287
va_end(args);
260288
}
261289

290+
void ShowErrorDirect(LPCTSTR szMsg)
291+
{
292+
ShowMessageDirect (FOREGROUND_RED | FOREGROUND_INTENSITY, szMsg);
293+
}
294+
262295
void ShowWarning(LPCTSTR szMsg, ...)
263296
{
264297
va_list args;
265298
va_start(args, szMsg);
266-
SetConsoleTextAttribute(g_hConsole, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
267-
_vtprintf(szMsg, args);
268-
SetConsoleTextAttribute(g_hConsole, g_wCurrentAttributes);
299+
ShowMessage(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY, szMsg, args);
269300
va_end(args);
270301
}
271302

303+
void ShowWarningDirect(LPCTSTR szMsg)
304+
{
305+
ShowMessageDirect(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY, szMsg);
306+
}
307+
272308
typedef NTSTATUS(WINAPI* RtlGetVersionFn)(
273309
PRTL_OSVERSIONINFOW lpVersionInformation);
274310

@@ -1261,6 +1297,7 @@ void ProcessFile(HANDLE f, ULONGLONG fileSize, LPCTSTR szFilePath, bool bQuiet,
12611297
g_bMismatchFound = true;
12621298

12631299
std::wstring szMsg = FormatString(L"Hash value mismatch for \"%s\"\n", szFilePath);
1300+
SanitizeString(szMsg);
12641301

12651302
if (g_threadsCount)
12661303
{
@@ -1271,7 +1308,7 @@ void ProcessFile(HANDLE f, ULONGLONG fileSize, LPCTSTR szFilePath, bool bQuiet,
12711308
}
12721309
else
12731310
{
1274-
if (!bQuiet) ShowWarning(szMsg.c_str());
1311+
if (!bQuiet) ShowWarningDirect(szMsg.c_str());
12751312
if (outputFile) _ftprintf(outputFile, szMsg.c_str());
12761313
}
12771314
}
@@ -1292,6 +1329,7 @@ void ProcessFile(HANDLE f, ULONGLONG fileSize, LPCTSTR szFilePath, bool bQuiet,
12921329
else
12931330
szMsg += szFilePath;
12941331
szMsg += L"\n";
1332+
SanitizeString(szMsg);
12951333

12961334
if (g_threadsCount)
12971335
{
@@ -1302,7 +1340,7 @@ void ProcessFile(HANDLE f, ULONGLONG fileSize, LPCTSTR szFilePath, bool bQuiet,
13021340
}
13031341
else
13041342
{
1305-
if (!bQuiet) ShowWarning(szMsg.c_str());
1343+
if (!bQuiet) ShowWarningDirect(szMsg.c_str());
13061344
if (outputFile) _ftprintf(outputFile, szMsg.c_str());
13071345
}
13081346
}
@@ -1323,12 +1361,13 @@ DWORD WINAPI OutputThreadCode(LPVOID pArg)
13231361
while (!g_bFatalError && (pOutput = (OUTPUT_ITEM*)InterlockedPopEntrySList(g_outputsList)))
13241362
{
13251363
p = pOutput->pParam;
1364+
SanitizeString(*p);
13261365
if (!pOutput->bQuiet)
13271366
{
13281367
if (pOutput->bError)
1329-
ShowError(p->c_str());
1368+
ShowErrorDirect(p->c_str());
13301369
else
1331-
ShowWarning(p->c_str());
1370+
ShowWarningDirect(p->c_str());
13321371
}
13331372
if (!pOutput->bSkipOutputFile) if (outputFile) _ftprintf(outputFile, p->c_str());
13341373
delete p;
@@ -1533,6 +1572,7 @@ DWORD HashFile(const CPath& filePath, Hash* pHash, bool bIncludeNames, bool bStr
15331572
if (It == digestList.end())
15341573
{
15351574
std::wstring szMsg = FormatString(_T("Error: file \"%s\" not found in checksum file.\n"), szFilePath);
1575+
SanitizeString(szMsg);
15361576

15371577
if (outputFile) _ftprintf(outputFile, szMsg.c_str());
15381578
if (g_bSkipError)
@@ -1542,7 +1582,7 @@ DWORD HashFile(const CPath& filePath, Hash* pHash, bool bIncludeNames, bool bStr
15421582
if (g_threadsCount)
15431583
AddOutputEntry(new std::wstring(szMsg), bQuiet, true, true);
15441584
else
1545-
ShowError(szMsg.c_str());
1585+
ShowErrorDirect(szMsg.c_str());
15461586
}
15471587
g_bMismatchFound = true;
15481588
return 0;
@@ -1626,7 +1666,7 @@ DWORD HashFile(const CPath& filePath, Hash* pHash, bool bIncludeNames, bool bStr
16261666
else
16271667
{
16281668
std::wstring szMsg = FormatString (_T("Failed to open file \"%s\" for reading (error 0x%.8X)\n"), szFilePath, GetLastError());
1629-
1669+
SanitizeString(szMsg);
16301670
if (outputFile && (!bSumMode || bSumVerificationMode)) _ftprintf(outputFile, szMsg.c_str());
16311671
if (g_bSkipError)
16321672
{
@@ -1637,7 +1677,7 @@ DWORD HashFile(const CPath& filePath, Hash* pHash, bool bIncludeNames, bool bStr
16371677
AddOutputEntry(new std::wstring(szMsg), bQuiet, true, true);
16381678
}
16391679
else
1640-
ShowError(szMsg.c_str());
1680+
ShowErrorDirect(szMsg.c_str());
16411681
}
16421682

16431683
if (bSumMode) g_bMismatchFound = true;
@@ -1679,7 +1719,8 @@ DWORD HashDirectory(const CPath& dirPath, Hash* pHash, bool bIncludeNames, bool
16791719
if (INVALID_HANDLE_VALUE == hFind)
16801720
{
16811721
dwError = GetLastError();
1682-
std::wstring szMsg = FormatString (_T("FindFirstFile failed on \"%s\" with error 0x%.8X.\n"), szDirPath, dwError);
1722+
std::wstring szMsg = FormatString (_T("FindFirstFile failed on \"%s\" with error 0x%.8X.\n"), szDirPath, dwError);
1723+
SanitizeString(szMsg);
16831724
if (outputFile && (!bSumMode || bSumVerificationMode)) _ftprintf(outputFile, szMsg.c_str());
16841725
if (g_bSkipError)
16851726
{
@@ -1688,7 +1729,7 @@ DWORD HashDirectory(const CPath& dirPath, Hash* pHash, bool bIncludeNames, bool
16881729
if (g_threadsCount)
16891730
AddOutputEntry(new std::wstring(szMsg), bQuiet, true, true);
16901731
else
1691-
ShowError(szMsg.c_str());
1732+
ShowErrorDirect(szMsg.c_str());
16921733
}
16931734
return 0;
16941735
}
@@ -1744,6 +1785,7 @@ DWORD HashDirectory(const CPath& dirPath, Hash* pHash, bool bIncludeNames, bool
17441785
if (dwError != ERROR_NO_MORE_FILES)
17451786
{
17461787
std::wstring szMsg = FormatString (TEXT("FindNextFile failed while listing \"%s\". \n Error 0x%.8X.\n"), szDirPath, dwError);
1788+
SanitizeString(szMsg);
17471789
FindClose(hFind);
17481790

17491791
if (outputFile && (!bSumMode || bSumVerificationMode)) _ftprintf(outputFile, szMsg.c_str());
@@ -1754,7 +1796,7 @@ DWORD HashDirectory(const CPath& dirPath, Hash* pHash, bool bIncludeNames, bool
17541796
if (g_threadsCount)
17551797
AddOutputEntry(new std::wstring(szMsg), bQuiet, true, true);
17561798
else
1757-
ShowError(szMsg.c_str());
1799+
ShowErrorDirect(szMsg.c_str());
17581800
}
17591801
return 0;
17601802
}
@@ -3159,7 +3201,7 @@ int _tmain(int argc, _TCHAR* argv[])
31593201
else
31603202
{
31613203
if (wcslen(g_szLastErrorMsg.c_str()))
3162-
ShowError(g_szLastErrorMsg.c_str());
3204+
ShowErrorDirect(g_szLastErrorMsg.c_str());
31633205
}
31643206

31653207
delete pHash;

0 commit comments

Comments
 (0)