إضافة الشيكات الفارغة المفقودة بعد malloc مع coccinelle

StackOverflow https://stackoverflow.com/questions/1716086

سؤال

أريد أن أكتب رقعة دلالية ل coccinelle., ، بحيث ستضيف if (ptr == NULL) ... الشيكات بعد المكالمات إلى Malloc حيث تكون مفقودة.

دعنا نقول أن لدي شفرة مصدر الإدخال التالية:

#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;
}

لقد كنت أحاول التوصل إلى تصحيح دلالي يفعل هذا، لكن لدي مشكلة في الحصول عليها للقيام بما أريد. مجرد إضافة اختبارات فارغة دون قيد أو شرط ليست مشكلة، والمشكلة هي عدم القيام بذلك عند عدم الحاجة. ما يلي هو ما لدي حاليا:

// 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();
+}

المشكلة مع هذا هو أنه لا يستبعد الحالات الموافق، وأنا لا أفهم كيفية توصيل القاعدتين. يمكن لأي شخص أن يساعدني في ذلك؟

فقط لتكون واضحة 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;
}
هل كانت مفيدة؟

المحلول

// البحث عن مكالمات إلى malloc @ اتصل بالتعبير ptr؛ موقف ص؛ ptr @ p = malloc (...)؛ // العثور على مكالمات موافق إلى malloc @ موافق @ التعبير ptr؛ موقف Call.P؛ ptr @ p = malloc (...)؛ ... متى! = PTR ((PTR == NULL || ...) | (PTR! = NULL || ...)) // إصلاح المكالمات السيئة إلى mallocdepends on! OK @ Expression PTR؛ موقف Call.P؛ ptr @ p = malloc (...)؛ + إذا (ptr == null) العودة؛
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top