Coverity 偏转:- 字符串长度计算错误 (BAD_ALLOC_STRLEN)
Coverity deflect: - String length miscalculation (BAD_ALLOC_STRLEN)
我有一个隐蔽偏转需要修复,但我不确定。我有一个函数 (void my_function(a_type *my_variable)
),其中包含以下有问题的代码行:
body = malloc(strlen(&((my_type*) *my_variable)->Param2.body[1]) +1);
其中 body
是一个 unsigned char*
。
Coverity 消息:
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
这样的论点不好?我看不出这里的实际问题是什么,所以我不确定这个解决方案 and/or 它的必要性。
其他信息是,&((my_type*) *my_variable)->Param2.body[1]
(简称 &Param2.body[1]
)将使用 strcpy
复制到 body
,例如:
strcpy(body, &((my_type *) *my_variable)->Param2.body[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);
我想你误解了括号。
覆盖建议中的+ 1
是外面 strlen(...)
我认为 Coverity 会担心,因为您想从索引 1 而不是索引 0 中获取 strlen
。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]
如 coverity 所建议
我得出的结论是 @rici 是正确的。考虑以下模拟:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Param2{
char* body;
}Param2;
int main()
{
Param2 test;
test.body = "test_string[=10=]";
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种与第一种相同)。在所有情况下,都可以在上图中看到分配的内存。现在,如果我们想从 2.byte (&body[1
]) 复制源字符串,这意味着示例中有 10 个字节的数据。并根据 strcpy documentation:
To avoid overflows, the size of the array pointed by destination shall
be long enough to contain the same C string as source (including the
terminating null character), and should not overlap in memory with
source.
我们还需要一个空终止符,这样我们就可以分配 11 个字节。 Coverity认为我们分配10个字节,建议分配12个。
但是正如我们所见,原始代码分配了 11 个字节,这正是我们在这里需要的字节数,这使得覆盖度偏离了误报。
我有一个隐蔽偏转需要修复,但我不确定。我有一个函数 (void my_function(a_type *my_variable)
),其中包含以下有问题的代码行:
body = malloc(strlen(&((my_type*) *my_variable)->Param2.body[1]) +1);
其中 body
是一个 unsigned char*
。
Coverity 消息:
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
这样的论点不好?我看不出这里的实际问题是什么,所以我不确定这个解决方案 and/or 它的必要性。
其他信息是,&((my_type*) *my_variable)->Param2.body[1]
(简称 &Param2.body[1]
)将使用 strcpy
复制到 body
,例如:
strcpy(body, &((my_type *) *my_variable)->Param2.body[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);
我想你误解了括号。
覆盖建议中的+ 1
是外面 strlen(...)
我认为 Coverity 会担心,因为您想从索引 1 而不是索引 0 中获取 strlen
。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]
如 coverity 所建议
我得出的结论是 @rici 是正确的。考虑以下模拟:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Param2{
char* body;
}Param2;
int main()
{
Param2 test;
test.body = "test_string[=10=]";
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种与第一种相同)。在所有情况下,都可以在上图中看到分配的内存。现在,如果我们想从 2.byte (&body[1
]) 复制源字符串,这意味着示例中有 10 个字节的数据。并根据 strcpy documentation:
To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.
我们还需要一个空终止符,这样我们就可以分配 11 个字节。 Coverity认为我们分配10个字节,建议分配12个。
但是正如我们所见,原始代码分配了 11 个字节,这正是我们在这里需要的字节数,这使得覆盖度偏离了误报。