gpt4 book ai didi

c - 使用 coccinelle 在 malloc 之后添加缺少的 NULL 检查

转载 作者:太空狗 更新时间:2023-10-29 15:00:00 24 4
gpt4 key购买 nike

我想为 coccinelle 写一个语义补丁, 这样它将在调用 malloc 之后添加 if (ptr == NULL) ... 检查它们。

假设我有以下输入源代码:

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

// memory leaks ignored

static void OK_simple(void)
{
char *ptr;
ptr = malloc(100);
if (ptr == NULL) {
return;
}
strcpy(ptr, "abcd");
}

static void NOT_OK_missing_NULL_check(void)
{
char *ptr;
ptr = malloc(100);
strcpy(ptr, "abcd");
}

static void NOT_OK_NULL_check_too_late(void)
{
char *ptr;
ptr = malloc(100);
strcpy(ptr, "abcd");
if (ptr == NULL) {
return;
}
}

static void OK_code_between_allocation_and_NULL_check(void)
{
char *ptr;
ptr = malloc(100);
printf("The NULL test does not have to be put immediately after\n");
if (ptr == NULL) {
return;
}
strcpy(ptr, "abcd");
}

static void OK_two_allocations(void)
{
char *ptr1, *ptr2;
ptr1 = malloc(100);
ptr2 = malloc(100);
if (ptr1 == NULL) {
return;
}
if (ptr2 == NULL) {
return;
}
strcpy(ptr1, "abcd");
strcpy(ptr2, "abcd");
}

static void NOT_OK_two_allocations_with_one_missing_NULL_check(void)
{
char *ptr1, *ptr2;
ptr1 = malloc(100);
ptr2 = malloc(100);
if (ptr1 == NULL) {
return;
}
strcpy(ptr1, "abcd");
strcpy(ptr2, "abcd");
}

int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
OK_simple();
NOT_OK_missing_NULL_check();
NOT_OK_NULL_check_too_late();
OK_code_between_allocation_and_NULL_check();
OK_two_allocations();
NOT_OK_two_allocations_with_one_missing_NULL_check();
return 0;
}

我一直在努力想出一个语义补丁来做这件事,但我很难让它做我想做的事。只是无条件地添加 NULL 测试是没有问题的,麻烦的是在不需要的时候不这样做。以下是我目前拥有的:

// this rule matches code that already have a NULL test

@already_have_proper_check@
statement S;
type T;
T* ptr;
expression E;
@@

ptr = malloc(E);
... when != ptr
if (ptr == NULL) S
//+dummy_change_just_to_verify_that_this_rule_matches();


// this rule adds NULL tests where missing

//@add_NULL_check depends on !already_have_proper_check@
@add_NULL_check@
type T;
//T* ptr != already_have_proper_check.ptr;
T* ptr;
expression E;
@@

ptr = malloc(E);
+if (ptr == NULL) {
+ insert_error_handling_here();
+}

问题是它不排除 OK 的情况,我不明白如何连接这两个规则。谁能帮我解决这个问题?

为了 100% 清楚,运行 coccinelle 后我想要的输出如下:

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

// memory leaks ignored

static void OK_simple(void)
{
char *ptr;
ptr = malloc(100);
if (ptr == NULL) {
return;
}
strcpy(ptr, "abcd");
}

static void NOT_OK_missing_NULL_check(void)
{
char *ptr;
ptr = malloc(100);
if (ptr == NULL) {
insert_error_handling_here();
}
strcpy(ptr, "abcd");
}

static void NOT_OK_NULL_check_too_late(void)
{
char *ptr;
ptr = malloc(100);
if (ptr == NULL) {
insert_error_handling_here();
}
strcpy(ptr, "abcd");
if (ptr == NULL) {
return;
}
}

static void OK_code_between_allocation_and_NULL_check(void)
{
char *ptr;
ptr = malloc(100);
printf("The NULL test does not have to be put immediately after\n");
if (ptr == NULL) {
return;
}
strcpy(ptr, "abcd");
}

static void OK_two_allocations(void)
{
char *ptr1, *ptr2;
ptr1 = malloc(100);
ptr2 = malloc(100);
if (ptr1 == NULL) {
return;
}
if (ptr2 == NULL) {
return;
}
strcpy(ptr1, "abcd");
strcpy(ptr2, "abcd");
}

static void NOT_OK_two_allocations_with_one_missing_NULL_check(void)
{
char *ptr1, *ptr2;
ptr1 = malloc(100);
ptr2 = malloc(100);
if (ptr2 == NULL) {
insert_error_handling_here();
}
if (ptr1 == NULL) {
return;
}
strcpy(ptr1, "abcd");
strcpy(ptr2, "abcd");
}

int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
OK_simple();
NOT_OK_missing_NULL_check();
NOT_OK_NULL_check_too_late();
OK_code_between_allocation_and_NULL_check();
OK_two_allocations();
NOT_OK_two_allocations_with_one_missing_NULL_check();
return 0;
}

最佳答案

// find calls to malloc@call@expression ptr;position p;@@ptr@p = malloc(...);// find ok calls to malloc@ok@expression ptr;position call.p;@@ptr@p = malloc(...);... when != ptr( (ptr == NULL || ...)| (ptr != NULL || ...))// fix bad calls to malloc@depends on !ok@expression ptr;position call.p;@@ptr@p = malloc(...);+ if (ptr == NULL) return;

关于c - 使用 coccinelle 在 malloc 之后添加缺少的 NULL 检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1716086/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com