-1

我有一个覆盖偏转要修复,但我不确定。我有一个函数 ( void my_function(a_type *my_variable)) 有以下有问题的代码行:

body = malloc(strlen(&((my_type*) *my_variable)->Param2.body[1]) +1);

哪里bodyunsigned char*

覆盖率消息:

String length miscalculation (BAD_ALLOC_STRLEN)
Using "strlen(((my_type *)*my_variable)->Param2.body + 1)" 
instead of "strlen(((my_type *)*my_variable)->Param2.body) + 1" 
as an argument to "malloc" might be an under-allocation.

现在,给定strlen函数调用,如下所示:

strlen(&((my_type*) *my_variable)->Param2.body[1])

这一行等同于:

strlen(&((my_type*) *my_variable)->Param2.body + 1)

所以这应该根据消息进行更改,结果将是:

body = malloc((strlen(&((my_type*) *my_variable)->Param2.body)+1) +1);

为什么不好这样的论点malloc?我看不出这里的实际问题是什么,所以我不确定这个解决方案和/或其必要性。

附加信息是,&((my_type*) *my_variable)->Param2.body[1](简单地&Param2.body[1])将被复制到bodyusing 中strcpy,例如:

strcpy(body, &((my_type *) *my_variable)->Param2.body[1]);
4

3 回答 3

1

不,...body[1]并且...body + 1相同。第一个类型是body数组的元素类型,第二个类型是ptr-to-element-type。再读一遍你的 C 书:-)

Coverity 试图告诉你,你犯了同样的错误

char foo[42];
/* write a string to foo */
bar = malloc (strlen(foo + 1)); /* which is strlen(&foo[1]) */

当正确的代码是

bar = malloc (strlen(foo) + 1);
于 2016-03-30T13:11:43.493 回答
1

我想你误解了括号。

覆盖范围内的+ 1建议在外strlen(...)

我认为 Coverity 会担心,因为您想strlen从索引 1 而不是索引 0 中获取。Coverity 会期望索引 0 作为起点 - 例如:

body = malloc(strlen(&((my_type*) *my_variable)->Param2.body[0]) +1);
                                                             ^

这也是

body = malloc(strlen(((my_type*) *my_variable)->Param2.body) +1);
              ^                                            ^
            No & operator                                No [0]

正如coverage所建议的那样

于 2016-03-30T13:12:32.060 回答
0

我已经得出结论@rici是正确的。考虑以下模拟:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct Param2{
    char* body;
}Param2;

int main()
{
    Param2 test;
    test.body = "test_string\0";
    printf("%s, size: %d + 1 terminating null\n\n",test.body, strlen(test.body));

    printf("original:                %d \n", (strlen(&test.body[1]) + 1));
    printf("what coverity thinks:    %d \n", strlen(test.body + 1));
    printf("what coverity suggests:  %d \n", (strlen(test.body) + 1));
    printf("a more transparent way:  %d \n\n", (strlen(test.body + 1) + 1));

    return 1;
}

这是输出: ![在此处输入图像描述

共有三种情况(第 4 种与第 1 种相同)。对于所有情况,都可以在上图中看到分配的内存。现在,如果我们想从 2. byte ( &body[1]) 复制源字符串,这在示例中意味着 10 个字节的数据。并根据 strcpy文档

为避免溢出,destination 指向的数组的大小应足够长,以包含与 source 相同的 C 字符串(包括终止的空字符),并且不应在内存中与 source 重叠。

我们需要一个空终止给我们分配 11 个字节。Coverity 认为我们分配了 10 个字节,并建议分配 12 个。

但正如我们所看到的,原始代码分配了 11 个字节,这正是我们需要的字节数,这使得覆盖率偏转误报。

于 2016-04-07T11:58:15.573 回答