Mac解决方案;“安全”;“替代方案”;“不安全”;C/C++;标准库函数?

Mac解决方案;“安全”;“替代方案”;“不安全”;C/C++;标准库函数?,c,macos,gcc,C,Macos,Gcc,Mac上最好的一站式“安全”C库解决方案是什么?我在“safe”/“unsafe”中使用引号,因为对于某些标准库函数或其假定改进的替代函数的好处存在很多争论 许多传统的标准C库函数(例如,vfprintf)被认为是不安全的,因为可能存在缓冲区溢出或其他安全问题 在Windows上,Microsoft C/C++编译器将“_s”函数(例如,vfprintf_s)编译为标准库调用的更安全的替代方法。这些功能不是直接替换,因为它们具有提供附加安全信息(例如缓冲区长度)所需的不同签名。它们还提供其他功能

Mac上最好的一站式“安全”C库解决方案是什么?我在“safe”/“unsafe”中使用引号,因为对于某些标准库函数或其假定改进的替代函数的好处存在很多争论

许多传统的标准C库函数(例如,
vfprintf
)被认为是不安全的,因为可能存在缓冲区溢出或其他安全问题

在Windows上,Microsoft C/C++编译器将“_s”函数(例如,
vfprintf_s
)编译为标准库调用的更安全的替代方法。这些功能不是直接替换,因为它们具有提供附加安全信息(例如缓冲区长度)所需的不同签名。它们还提供其他功能,如无效格式字符串检测、不同的文件安全性等。据我所知,这种实现在Mac上不可用

苹果(或第三方)是否提供了类似的东西用于OSX上的GCC

特别是,我正在寻找至少以下功能的“安全”实现:

fopen vfprintf vsprintf sprintf strncpy strcat


请注意:这个问题是关于Mac的。我不是在征求你对微软实现的意见(除非它可以在Mac上使用)。尽管其中一些函数可能很容易自己编写,但并非所有函数都是如此。我不是问自己如何写这些。我不是在询问如何使用STL类来实现这一点的技巧。我不是问如何关闭警告。我的特殊需要非常具体。我试图找出一个最佳实践macapi,它在增加安全性的同时,尽可能类似于传统的C库调用。当然,在Mac和Windows(以及其他操作系统)上工作的可移植实现会更好。

您希望使用以下替代sprintf和vsprintf:

snprintf(buffer, buffer_size, fmt_string, args, ...);
vsnprintf(buffer, buffer_size, fmt_string, valist);
除了strcpy、strncpy、strcat和strncat,您希望我们:

strlcpy(dest, src, dest_size);
strlcat(dest, src, dest_size);
有一个重要的方法是strn函数不能被strl函数替代。如果要复制以非0结尾的字符串,strn函数允许您通过将长度设置为复制量和目标缓冲区大小的较小值来实现。strl函数不这样做,只在源字符串以0结尾时工作


不确定fopen或vfprintf是如何被视为不安全的。

由于OSX的用户区是基于,您确实有一些更好的功能,例如。

首先,从MSDN打印有关“安全/不安全”功能的文档并刻录它

福彭

和fopen_s一样安全。。。除非您是白痴,并且假设返回的指针不是NULL,或者提供NULL作为输入参数

vfprintf vsprintf sprintf 
只是MS不支持C99,请使用
snprintf
系列

 strncpy
如果你阅读说明书,它是完全安全的

strcpy strcat
使用
strncpy
strncat
并阅读规范。(即strncpy不能以null结尾)

所以。。。再次:


打印MSDN中有关“安全/不安全”功能的文档并将其刻录

C标准已经有了一套这些功能的“安全”版本。
(对于术语safe的特定定义)

snprintf()(和系列)提供了您需要的安全功能。缓冲区溢出检查。
此外,gcc编译器还进行格式字符串验证(但比MS更好,因为验证是在编译时完成的)

另见:

微软已经编写了一份技术报告,部分是在微软的鼓励下(我相信)。它标准化了各种功能的接口,如
vsnprintf\u s()
。然而,遗憾的是,该标准定义的接口与Microsoft定义的接口不兼容,因此使得该标准在很大程度上不相关

例如,TR 24731-1说
vsnprintf_s()
的接口是:

#define _ _STDC_WANT_LIB_EXT1_ _ 1
#include <stdarg.h>
#include <stdio.h>
int vsnprintf_s(char * restrict s, rsize_t n,
                const char * restrict format, va_list arg);
int vsnprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   va_list argptr 
);
参数

  • 缓冲区-输出的存储位置
  • sizeOfBuffer—输出缓冲区的大小
  • count—要写入的最大字符数(不包括终止的null)或_TRUNCATE
  • 格式-格式规范
  • argptr-指向参数列表的指针

请注意,这不仅仅是类型映射的问题:固定参数的数量不同,因此不可调和。我(大概也是标准委员会)也不清楚“sizeOfBuffer”和“count”都有什么好处;它看起来像两次相同的信息(或者,至少,代码通常使用两个参数的相同值编写)。

摘要:在Mac上,有几个API和编译器选项提供了C标准库函数的更安全的替代方案。以下是一些与之相比:

C MSVC提供商MAC解决方案 --------------------------------------------------------------------------------- fopen fopen_s C无,假设fopen是安全的 vfprintf vfprintf\u的GCC\u警告\u类型检查\u调用\u PRINTF(1) vsprintf vsprintf_s GCC,C99 GCC_WARN_TYPECHECK_调用_PRINTF,vsnprintf(2) sprintf sprintf\u s GCC,C99 GCC\u警告\u类型检查\u调用\u PRINTF,snprintf(3) strncpy strncpy_s BSD strlcpy(4) strcpy strcpyu BSD strlcpy strcat strcat strcat_BSD strlcat(5) (1)
GCC\u WARN\u TYPECHECK\u CALLS\u TO\u PRINTF
是一个与GCC命令行选项相对应的XCode配置选项。此选项会生成编译器警告,指出参数类型和静态格式字符串之间存在分歧。还有许多其他选项可以控制GCC对格式字符串的处理。您甚至可以使用GCC的
format
在自己的函数上启用格式字符串检查

(2) 和(3)来自C标准库的C99版本(在Mac上的GCC中提供)
int vsnprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   size_t count,
   const char *format,
   va_list argptr 
);
C MSVC PROVIDERS MAC SOLUTION --------------------------------------------------------------------------------- fopen fopen_s C none, assume fopen is safe vfprintf vfprintf_s GCC GCC_WARN_TYPECHECK_CALLS_TO_PRINTF(1) vsprintf vsprintf_s GCC, C99 GCC_WARN_TYPECHECK_CALLS_TO_PRINTF, vsnprintf(2) sprintf sprintf_s GCC, C99 GCC_WARN_TYPECHECK_CALLS_TO_PRINTF, snprintf(3) strncpy strncpy_s BSD strlcpy(4) strcpy strcpy_s BSD strlcpy strcat strcat_s BSD strlcat(5)