【问题标题】:FreeWRL, "format not a string literal and no format arguments"FreeWRL,“格式不是字符串文字,也没有格式参数”
【发布时间】:2014-01-09 12:23:51
【问题描述】:

所以我正在尝试构建 freewrl android 库,它是在原生 android 代码中,这意味着在 C 中。我绝不熟悉 C,并且认为既然包含了一个构建脚本,它应该开箱即用。 - 它不是。 在解决了一些小问题后,这就是我现在正在查看的内容:

/opt/freewrl/Android/jni/../../freex3d/src/lib/main/ConsoleMessage.c: In function 'fwvsnprintf':
/opt/freewrl/Android/jni/../../freex3d/src/lib/main/ConsoleMessage.c:333:4: error: format not a string literal and no format arguments [-Werror=format-security]
cc1: some warnings being treated as errors
make: *** [/opt/freewrl/Android/obj/local/armeabi/objs/FreeWRL/__/__/freex3d/src/lib/main/ConsoleMessage.o] Error 1

ConsoleMessage.c 中相关的代码如下:

count += sprintf(tempbuf, format);/* printf it verbatim             */

这是以下构造或函数的一部分:

int fwvsnprintf(char *buffer,int buffer_length, const char *fmt, va_list ap)
{
    int i,j,count;
    //char tempbuf[STRING_LENGTH];
    //char format[STRING_LENGTH];
    char *tempbuf;
    char *format;
    char c;
    double d;
    unsigned u;
    char *s;
    void *v;
    tempbuf = malloc(buffer_length);
    format = malloc(buffer_length);
    count = 0;
    buffer[0] = '\0';
    while (*fmt) 
    {
        tempbuf[0] = '\0';
        for (j = 0; fmt[j] && fmt[j] != '%'; j++) {
            format[j] = fmt[j]; /* not a format string  */
        }

        if (j) {
            format[j] = '\0';
            count += sprintf(tempbuf, format);/* printf it verbatim             */
            fmt += j;
        } else {
            for (j = 0; !isalpha(fmt[j]); j++) {     /* find end of format specifier */
                format[j] = fmt[j];
                if (j && fmt[j] == '%')             /* special case printing '%'        */
                    break;
            }
            format[j] = fmt[j];         /* finish writing specifier      */
            format[j + 1] = '\0';           /* don't forget NULL terminator */
            fmt += j + 1;

            switch (format[j]) {             /* cases for all specifiers         */
            case 'd':
            case 'i':                       /* many use identical actions    */
                i = va_arg(ap, int);         /* process the argument     */
                count += sprintf(tempbuf, format, i); /* and printf it       */
                break;
            case 'o':
            case 'x':
            case 'X':
            case 'u':
                u = va_arg(ap, unsigned);
                count += sprintf(tempbuf, format, u);
                break;
            case 'c':
                c = (char) va_arg(ap, int);     /* must cast!            */
                count += sprintf(tempbuf, format, c);
                break;
            case 's':
                s = va_arg(ap, char *);
                /* limit string to a certain length */
                if ((strlen(s) + count) > buffer_length) {
                    char tmpstr[100];
                    int ltc;
                    ltc = (int) strlen(s);
                    if (ltc>80) ltc=80;
                    strncpy (tmpstr, s, ltc);
                    tmpstr[ltc] = '.'; ltc++;
                    tmpstr[ltc] = '.'; ltc++;
                    tmpstr[ltc] = '.'; ltc++;
                    tmpstr[ltc] = '\0';

                    count += sprintf (tempbuf, format, tmpstr);
                } else count += sprintf(tempbuf, format, s);
                break;
            case 'f':
            case 'e':
            case 'E':
            case 'g':
            case 'G':
                d = va_arg(ap, double);
                count += sprintf(tempbuf, format, d);
                break;
            case 'p':
                v = va_arg(ap, void *);
                count += sprintf(tempbuf, format, v);
                break;
            case 'n':
                count += sprintf(tempbuf, "%d", count);
                break;
            case '%':
                count += sprintf(tempbuf, "%%");
                break;
            default:
                ERROR_MSG("ConsoleMessage: invalid format specifier: %c\n", format[j]);
            }
        }
        if( (strlen(tempbuf) + strlen(buffer)) < (buffer_length) -10) 
        {
            strcat (buffer,tempbuf);
        }
    }
    free(tempbuf);
    free(format);
    return 1;
}

据我所知,format 填充了 fmt 的内容,这是一个参数,直到读取 %tempbuf 看起来像一个 '\0' 所以对我来说是一个空字节。 但这是我所能得到的,所以我很感激任何帮助,因为我正在努力构建这个库。 提前谢谢你。

【问题讨论】:

    标签: c android-ndk printf


    【解决方案1】:

    根据错误,您的makefile 中的-Werror=format-security 标志似乎默认启用,并且最好不要像printfscanf 函数那样对字符串格式造成任何安全问题。所以警告在您的来源中被视为错误。因此,如果您不担心安全性,请禁用它。或者请在任何地方更改代码,发现如下相同的语句可能是它删除错误。

    count += sprintf(tempbuf,"%s",format);/* printf it verbatim             */
    

    为了安全使用snprintf点赞

    count += snprintf(tempbuf,buffer_length,"%s",format);/* printf it verbatim             */
    

    【讨论】:

    • 谢谢! “%s”修复了它。
    猜你喜欢
    • 2010-12-13
    • 2011-05-24
    • 2014-12-23
    • 2011-08-12
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 2013-06-20
    • 2013-08-25
    相关资源
    最近更新 更多