|
-
July 13th, 2010, 07:50 PM
#8
Re: allow literal string only
As pointed above, there's no way to detect this at a compilation time, but it doesn't mean that you can't do it at a runtime though. As far as I know the latest Operating Systems (since Vista) are employing a different (i.e. more secure) memory management strategy, as well as a different approach to loading executables. And, this means that you can use it for the purpose of your question. So the whole idea is to test whether a string is writable in memory and if so, it will mean that it is not a static string. In other words, anything that is not declared static is allocated either on the stack or from a heap and is writable.
OK, so here's the code:
Add the following in the declaration of one of your globally accessible classes:
Code:
static __forceinline void DebuggerTestConstStringPtr(LPCTSTR pString, int nCodeLine, LPCSTR pCodeFile)
{
// #ifdef _DEBUG
__try
{
BOOL bNonWritableMem = ::IsBadWritePtr((LPVOID)pString, (lstrlen(pString) + 1) * sizeof(TCHAR));
ASSERT(bNonWritableMem == TRUE); //Assertion here means you passed a non-static string
if(bNonWritableMem != TRUE)
{
TRACE(_T("Non-static string passed on line %d in %s\n"), nCodeLine, pCodeFile);
}
}
__except(1)
{
ASSERT(FALSE); //Bad string pointer
TRACE(_T("Bad string passed on line %d in %s\n"), nCodeLine, pCodeFile);
}
// #endif
}
and then you can simply call this method from anywhere in your code:
Code:
static const TCHAR sz[] = _T("this is also ok");
CGlobalClass::DebuggerTestConstStringPtr(sz, __LINE__, __FILE__);
CGlobalClass::DebuggerTestConstStringPtr(_T("This is OK"), __LINE__, __FILE__);
TCHAR sz2[] = _T("this is not ok");
CGlobalClass::DebuggerTestConstStringPtr(sz2, __LINE__, __FILE__); //ASSERTs!
CString str("MFC string is not ok");
CGlobalClass::DebuggerTestConstStringPtr(str, __LINE__, __FILE__); //ASSERTs!
std::string str2("STL string is not ok");
CGlobalClass::DebuggerTestConstStringPtr(str2.c_str(), __LINE__, __FILE__); //ASSERTs!
NOTE that you have to run it on Vista or Windows 7 (and possibly compile with a newer version of Visual Studio) to be able to track writable memory. It is also not advisable to keep the IsBadWritePtr API in your distribution build, since that API is not safe (read MSDN for more into). You may also want to skip using the /NXCOMPAT, and /DYNAMICBASE compiler directives.
Last edited by ahmd; July 15th, 2010 at 03:49 PM.
Reason: Code typo
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|