这里有一个关于 C++ Stackwalker 的问题: https://github.com/JochenKalmbach/StackWalker
#define _TRUNCATE ((size_t)-1)
enum
{
STACKWALK_MAX_NAMELEN = 1024
};
void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName)
{
CHAR buffer[STACKWALK_MAX_NAMELEN];
size_t maxLen = STACKWALK_MAX_NAMELEN;
#if _MSC_VER >= 1400
maxLen = _TRUNCATE;
#endif
_snprintf_s(buffer, maxLen, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n",
szSearchPath, symOptions, szUserName);
}
maxlen 首先设置为 1024,然后如果 VC++ 版本 >= 1400(它是),则将其设置为(无符号)-1,换句话说至少为 UINT_MAX。
然后maxlen传给了_snprintf_s,所以如果字符串大于1024个字符会再次造成缓冲区溢出。
我是不是漏掉了什么?将 maxlen 设置为 UINT_MAX 的原因可能是什么?使用安全字符串函数但没有安全性?
最佳答案
_snprintf_s
(一个 Visual Studio 特定函数)的重载只能在 C++ 中使用,前提是可以从第一个参数推导出缓冲区长度。
参见 documentation 中 Remarks
下的第二段有关 _TRUNCATE
魔法值及其作用的描述。
但请注意,对于早期版本的 VS,代码使用 _snprintf
实现此功能,它对宏 _TRUNCATE
一无所知:
#if _MSC_VER < 1400
// ...
#define _snprintf_s _snprintf
为了能够使用_snprintf
,他必须安排缓冲区长度才能通过。 snprintf
没有可以推断字符缓冲区参数长度的模板化重载。此外,他需要 #define _TRUNCATE
因为在那些相同的旧版本中,它不存在于 stdlib.h
中。
总而言之,对于不必要的复杂非标准库函数,这让我觉得这是一个非常笨拙的解决方法。
关于c++ - 将 (size_t)-1 传递给 snprintf_s,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52326480/