How to check user entered printf format string in parameter list?

I have a list of numbers and want to give my users the opportunity to enter a printf style format string to indicate how numbers should be displayed.

How can I check the user entered format string in the parameter list? Incorrect input should not cause the program to crash, and I want to avoid any string type attacks.

I don't care if validation processes only the format parameters specified in POSIX or a specific compiler supercomplex. Is there any library call to do this, or should I write it myself?

Clarification: I need 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" );

, . , .

, isValidFormat():

  • "% f% g% e%.1f"
  • "Foo -% g, Bar -% g"
  • ""

:

  • "% s"
  • "Foo is% d"
+3
6

printf. printf , . , , .

, printf?

, -, printf. , printf , . . , .

+1

- , . , , , . , (double) :

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

, , :

([^%]|%%)*

, , ( ^ $ ), .

+1

(POSIX C) , , . , . , , .

0

, .

switch ( <variable> ) {
case accetable-value_1:
  Code to execute if <variable> == accetable-value_1
  break;
case accetable-value_2:
  Code to execute if <variable> == accetable-value_2
  break;
...
default:
  error: This is not a valid value, please enter a valid value
  break;
}
0

RRDtool .

#include <glib.h>

static int bad_format_check(const char *pattern, char *fmt) {
    GError *gerr = NULL;
    GRegex *re = g_regex_new(pattern, G_REGEX_EXTENDED, 0, &gerr);
    GMatchInfo *mi;
    if (gerr != NULL) {
        // rrd_set_error("cannot compile regular expression: %s (%s)", gerr->message,pattern);
        return 1;
    }
    int m = g_regex_match(re, fmt, 0, &mi);
    g_match_info_free (mi);
    g_regex_unref(re);
    if (!m) {
        // rrd_set_error("invalid format string '%s' (should match '%s')",fmt,pattern);
        return 1;
    }
    return 0;
}

#define SAFE_STRING "(?:[^%]+|%%)*"

int bad_format_imginfo(char *fmt){
    return bad_format_check("^" SAFE_STRING "%s" SAFE_STRING "%lu" SAFE_STRING "%lu" SAFE_STRING "$",fmt);
}
#define FLOAT_STRING "%[-+ 0#]?[0-9]*(?:[.][0-9]+)?l[eEfF]"

int bad_format_axis(char *fmt){
    return bad_format_check("^" SAFE_STRING FLOAT_STRING SAFE_STRING "$",fmt);
}

int bad_format_print(char *fmt){
    return bad_format_check("^" SAFE_STRING FLOAT_STRING SAFE_STRING "%s" SAFE_STRING "$",fmt);
}
0

- sprintf ( printf) , sprintf.

-2

All Articles