我希望摆脱大型C ++项目中sprintf
之类的不安全函数的所有用法。
我希望errors or at least warnings
能够向我展示所有需要进一步审核的事件。
我知道,在OpenBSD上有这样的警告,但我在Linux上。如果我尝试为sprintf
定义宏,则会在<cstdio>
标头中出现错误。除了修补系统标题外,还有什么好主意吗?
修改 另外一个挑战是,在自行开发的C ++字符串类中有一个sprintf函数。因此,只需要对sprintf进行调整就会产生很多误报。
答案 0 :(得分:5)
即使我完全同意@Matt这些功能并不坏,而且你在禁止这种行为时也是如此,这里就是这样做的。
今天是标题日的补丁:
__attribute__ ((deprecated))
。没有修补标题?
尽管如此,直接采取行动可能会更好:只需grep你自己的项目文件 您甚至可以将该搜索保存为重新应用的脚本。
使用预处理器(注意,我们正在更改保留标识符,这很糟糕!):
像这样添加文件“explosive_security.h”:
inline static int my_deprecated() __attribute__ ((deprecated)) {return 0;}
#undef strcmp
#define strcmp (my_deprecated(), strcmp)
并在所有其他包含之后包含 这应该在大多数情况下产生警告并且没有错误,但在某些情况下总是出错。
答案 1 :(得分:1)
基于@Deduplicator和@alastair的答案,我提出了以下解决方案,这对我有用:
在头文件中,每个编译单元都包含gcc的-include
选项(以前就已经存在),我添加了这些行:
#ifdef __cplusplus
#include <cstdio>
#else
#include <stdio.h>
#endif
#undef sprintf
extern "C" {
int sprintf(char *, const char*, ...) __attribute__((error("!!!DON'T USE sprintf(), USE snprintf() INSTEAD!!!")));
}
当然,您可以将error
替换为warning
。 (出于某种原因deprecated
在我的设置中没有产生警告,没有进一步的研究,为什么。)
感谢所有贡献者!
答案 2 :(得分:0)
使用简单的#define
,而不是更复杂的#undef sprintf
#define sprintf __DO_NOT_CALL_SPRINTF
。例如
#undef sprintf
#define sprintf(s,f,...) __DO_NOT_CALL_SPRINTF(s, f, __VA_ARGS__)
比
更有可能没有问题#include
如果您仍然遇到问题,请确保在使用#define
之前#ifdef __cplusplus
#include <cstdio>
#else
#include <stdio.h>
#endif
#undef sprintf
#define sprintf __DO_NOT_CALL_SPRINTF
所有相关标题;一个简单的方法是创建一个项目范围的头文件(称之为&#34; safety.h&#34;)并在该标题内,例如。
{{1}}
当然,所有这些都可能比它真正的价值更麻烦。