gpt4 book ai didi

c - 当 vsnprintf 不可用时安全地格式化字符串

转载 作者:行者123 更新时间:2023-12-01 13:18:19 25 4
gpt4 key购买 nike

我正在编写需要格式化字符串的代码,我想避免缓冲区溢出。

我知道如果 vsnprintf 可用(从 C99 开始)我们可以:

char* formatString(const char *format, ...)
{
char* result = NULL;
va_list ap;
va_start(ap, format);

/* Get the size of the formatted string by getting vsnprintf return the
* number of remaining characters if we ask it to write 0 characters */
int size = vsnprintf(NULL, 0, format, ap);

if (size > 0)
{
/* String formatted just fine */
result = (char *) calloc(size + 1, sizeof(char));
vsnprintf(result, size + 1, format, ap);
}

va_end(ap);
return result;
}

我想不出在 C90 中做类似事情的方法(没有 vsnprintf)。如果事实证明如果不编写极其复​​杂的逻辑就不可能实现,我很乐意为结果设置最大长度,但我不确定如何在不冒缓冲区溢出风险的情况下实现这一点。

最佳答案

C99 之前的版本没有提供简单的解决方案来格式化字符串,并具有防止缓冲区溢出的高度安全性。

正是那些讨厌的 "%s""%[]""%f" 格式说明符需要非常小心考虑他们潜在的长期输出。因而需要这样的功能。 @Jonathan Leffler

为了使用那些早期的编译器,代码必须分析format 和参数以找到所需的大小。到那时,代码几乎就可以让您拥有完整的 my_vsnprintf()。我会为此寻求现有的解决方案。 @user694733 .


即使使用 C99,*printf() 也有环境限制。

The number of characters that can be produced by any single conversion shall be at least 4095. C11dr §7.21.6.1 15

所以任何试图char buf[10000]的代码; snprintf(buf, sizeof buf, "%s", long_string); 即使有足够的 buf[]strlen(long_string) > 4095 也会出现问题.

这意味着快速而肮脏的代码可以计算 % 和格式长度,并做出所需大小不超过的合理假设:

size_t sz = 4095*percent_count + strlen(format) + 1;

当然,对说明符的进一步分析可能会导致更保守的 sz。继续往下 path我们 end编写我们自己的 my_vsnprintf()


即使使用您自己的 my_vsnprintf()安全性 也不过如此。没有运行时检查 format(可能是动态的)是否与以下参数匹配。为此需要一种新方法。

C99 解决方案厚颜无耻的 self 宣传以确保匹配说明符和参数:Formatted print without the need to specify type matching specifiers using _Generic .

关于c - 当 vsnprintf 不可用时安全地格式化字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52537188/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com