编写一个类似 printf 的函数,它可以清理第一个参数之后的所有参数,使其摆脱 `%` 符号

Posted

技术标签:

【中文标题】编写一个类似 printf 的函数,它可以清理第一个参数之后的所有参数,使其摆脱 `%` 符号【英文标题】:Write a function like printf, that can sanitize all arguments after the first to be free from the `%` symbol 【发布时间】:2017-02-05 19:25:10 【问题描述】:
user_input = "%s%s%s%s%s%s%s%s";
printf("user input is: %s", user_input);

...崩溃!

以上行导致错误。我想编写一个可以像printf 一样使用的函数,但可以在第一个参数之后清理所有参数,以确保它们不包含% 符号。该函数应该像'printf'一样使用,因为它可以接受任意数量的参数,并以相同的方式打印出一个字符串。如果其他参数包含% 符号,我只想在将其放入格式字符串之前取出该符号。

如果这个新函数被称为safe_printf,我希望行为是这样的:

user_input = "%s%s%s%s%s%s%s%s";
safe_printf("user input is: %s, user_input);

用户输入是:ssssssss

似乎编写这样的函数可能是不可能的,(我不知道如何预处理 va_list 中的 char *s 不知道有多少)如果是这种情况,请告诉我。谢谢!

【问题讨论】:

显示的“用户输入”不会崩溃printf()。如果您使用printf(user_input, "just one argument") 或其他用户输入控制格式的变体,它可能会崩溃。您的safe_printf 调用不正确;你有第二个双引号......在错误的地方;或者实际上,它完全消失了。您的崩溃可能是因为您尝试从不可修改的字符串文字中删除百分比符号;它们通常不可写。 我对@9​​87654330@ 的行为感到困惑。我没有意识到格式字符串是唯一能够导致这种崩溃的参数。感谢您的澄清。 【参考方案1】:

如果将用户提供的输入传递给printf(3) 函数,则存在字符串格式化漏洞。您可以通过不允许这种情况发生来防止这种情况发生,永远。绝对没有理由使用动态格式字符串,因为您应该提前知道所需的格式,因此您可以通过使用 const char * 将格式字符串放入只读存储器中

【讨论】:

以上是关于编写一个类似 printf 的函数,它可以清理第一个参数之后的所有参数,使其摆脱 `%` 符号的主要内容,如果未能解决你的问题,请参考以下文章

类型安全的 printf

自定义条件包装printf

printf精度

学习C语言的第一天

TRACE函数怎么用

在调用asm函数之前调用printf与否的神秘副作用?