如何根据参数列表验证用户提供的printf格式字符串? [英] How to validate user-supplied printf format string against parameter list?

查看:125
本文介绍了如何根据参数列表验证用户提供的printf格式字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数字列表,希望给我的用户输入一个printf样式的格式字符串来指定应该如何输出数字。



我可以验证用户提供的格式字符串对我的参数列表吗?格式不正确的输入不应该使程序崩溃,我想避免任何格式字符串攻击。

我不在乎验证是否处理POSIX中指定的格式选项,编译器特定的超集。是否有任何图书馆电话这样做,或者我必须自己写?

澄清:
我需要的是像这样:

  float var1,var2,var3,var4; 
// var1 .. var2由程序给出
const char * userSupplied = getFormatStringFromUser();
$ b $ if(isValidFormat(userSupplied,float,float,float,float))
printf(userSupplied,var1,var2,var3,var4);
else
printf(您输入的格式无效!\\\
);

在这个例子中,我知道我有四个浮点数。
我想允许任何格式只能引用零到四个浮点数。

所以下面的格式字符串应该被 isValidFormat() em>:


  • %f%g%e%.1f

  • < %g,Bar is%g
  • Nothing



拒绝:
$ b


  • %s

  • Foo是%d

  • 解决方案

    为你写代码太多了,但是我会给你一个好的方法。为需要支持的每种类型的有效格式说明符设计正则表达式,然后使用它们为整个格式字符串构造一个更大的正则表达式,并查看它是否匹配。例如,一个浮点( double )参数的正则表达式看起来像这样:

     %[+  -  0#] * [0-9] *([。] [0-9] +)?[aefgAEFG] 

    在格式说明符之间的任何地方出现的正则表达式的正则表达式看起来像这样:

     ([^%] | %%)* 

    坚持整个字符串匹配正则表达式(在末尾使用 ^ $ 锚点)而不仅仅是一个子字符串。


    I have a list of numbers and want to give my users the option to enter a printf-style format string to specify how the numbers should be output.

    How can I validate the user-supplied format string against my parameter list? Malformed input should not crash the program, and I want to avoid any format string attacks.

    I do not care if the validation handles just the format options specified in POSIX or the compiler specific superset. Is there any library call to do this, or will I have to write it myself?

    Clarification: What I need is something like this:

    float var1, var2, var3, var4;
    // var1 .. var2 are given by the program
    const char * userSupplied = getFormatStringFromUser();
    
    if( isValidFormat( userSupplied, "float", "float", "float", "float" ) )
        printf( userSupplied, var1, var2, var3, var4 );
    else
        printf( "The format you gave was invalid!\n" );
    

    In this example, I know that I have four floats. I want to allow any format that only references zero to four floats.

    So the following format strings should be allowed by isValidFormat():

    • "%f %g %e %.1f"
    • "Foo is %g, Bar is %g"
    • "Nothing"

    While the following should be rejected:

    • "%s"
    • "Foo is %d"

    解决方案

    Writing the code for you is too much work, but I'll give you a good approach. Design regular expressions for the valid format specifiers for each type you need to support, then use them to construct a larger regular expression for the entire format string and see if it matches. For example, a floating point (double) argument's regex would look something like:

    %[+- 0#]*[0-9]*([.][0-9]+)?[aefgAEFG]
    

    And a regex for literal text that could appear anywhere between format specifiers would look something like:

    ([^%]|%%)*
    

    Make sure when matching the format string you insist that the whole string match the regex (use ^ and $ anchors at the ends) and not just a substring.

    这篇关于如何根据参数列表验证用户提供的printf格式字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆