Mario
Mario

Reputation: 14741

CString.Format crashes in 32-bit

I have a CString format which causes a crash in 32-bit Unicode MFC Static/VS2013 project in SDK file output.c line 1629 while (i-- && *pwch)

bool MyClass::Function1(LPCTSTR sAppName, HKEY hKey, LPCTSTR tcszValue1, LPCTSTR tcszValue2, LPCTSTR tcszValue3, BOOL bValue)
{     
    __int64 nAppId=0;
    __int64 nId2=0;
    sSql.Format(_T("INSERT INTO Table (AppId, Id2, RegPath, RegKey, RegValueName, 
         bRecurseDelete, RemoveIt) VALUES ('%d', '%d', '%s', '%s', '%s', '%d', 1)"), 
         nAppId, nId2, tcszValue1, tcszValue2, tcszValue3, bValue);
}

When I compile it in 64-bit it works without any problem, in 32-bit it crashes when sValue3 is empty (but not the first time, on the 4th call to CString.Format when sValue is empty)

Upvotes: 1

Views: 1088

Answers (2)

Jabberwocky
Jabberwocky

Reputation: 50778

You must use the %lld format specifier instead of the %d specifier.

In the 32 bit world, %d expects a 32 bit integer. But you provide 64 bit integers as arguments. Therefore you get undefined behaviour because Format will completly mix up the arguments.

Upvotes: 3

xMRi
xMRi

Reputation: 15355

Bad! You are not allowed to use a CString object in a Format statement. Always use GetString!

CString sValue1 = tcszValue1;
CString sValue2 = tcszValue2;
CString sValue3 = tcszValue3;

sSql.Format(_T("INSERT INTO Table (AppId, Id2, RegPath, RegKey, RegValueName, bRecurseDelete, RemoveIt) VALUES ('%d', '%d', '%s', '%s', '%s', '%d', 1)"), 
    nAppId, nId2, sValue1.GetString(), sValue2.GetString(), sValue3.GetString(), bValue);

Upvotes: 0

Related Questions