Can the input and output strings to sprintf() be the same?

后端 未结 2 1795
生来不讨喜
生来不讨喜 2020-12-10 10:39

I have used this type of convention many times in my code in the past:

strcpy ( cTmpA, \"hello\" );
sprintf ( cTmpA, \"%s world\", cTmpA );

2条回答
  •  执笔经年
    2020-12-10 11:32

    Most implementations of sprintf() don't copy the format string and instead use a pointer inside the string you passed. If format and output point to the same memory, that will lead to odd results.

    And you should really use snprintf() which protects you against buffer overflows.

    To find all calls, put #define sprintf +++ into a common header find and recompile all sources. That should give you a list of errors along with the file name and line numbers :) Or use recursive search'n'replace of your IDE.

    If you want to trim this list down to the ones where you use the same pointer for both arguments, use this macro:

    #define sprintf(output,format,...) check_sprintf(__FILE__,__LINE__,output,format,....)
    

    Note that not all compilers support macros with varargs. Then define a new function check_sprintf:

    int check_sprintf (char*filename,int line,char*output,char*format,...) {
        va_list args;
        int len;
    
        if(output==format) {
            fprintf(stderr,
                 "Output and format are the same at %s:%d", filename, line);
                 abort();
        }
    
        va_start (args, format);
        len = vsprintf (output, format, args);
        va_end (args);
    
        return len;   
    }
    

    [EDIT] I just saw that you're talking about the output and the first argument. You can reuse the code from above and call va_arg() to get the first argument and use that in the compare.

提交回复
热议问题