From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2209) id 561793858C83; Fri, 2 Dec 2022 02:31:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 561793858C83 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1669948285; bh=x5lybEJUyoGVPhS41ZoyYHoI7I4or8A3ruWwECU7jXQ=; h=From:To:Subject:Date:From; b=Gdacs2z5cLHpo5m/iBsuGBn4wOj6AKnHObjeTpRayURBkRzlgKHNi7pcrGbL3y5no 8cypsck79ip3Oz6CfvwkO1G513Fnn6lQjLkCn/6cj+DuPPQ7MOm/FpdrGkKVwPm6rN CQMeGMcUzcdXQiiV/+3cYibDoEXEVOOuiedRZUPE= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: David Malcolm To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-4455] analyzer: add test coverage for string ops X-Act-Checkin: gcc X-Git-Author: David Malcolm X-Git-Refname: refs/heads/master X-Git-Oldrev: e055e6db974d8b8950b30859a853e0aee74e20c2 X-Git-Newrev: 5cb7d28dcfb11a2810db55b0bbd71fe562bdc2a3 Message-Id: <20221202023125.561793858C83@sourceware.org> Date: Fri, 2 Dec 2022 02:31:25 +0000 (GMT) List-Id: https://gcc.gnu.org/g:5cb7d28dcfb11a2810db55b0bbd71fe562bdc2a3 commit r13-4455-g5cb7d28dcfb11a2810db55b0bbd71fe562bdc2a3 Author: David Malcolm Date: Thu Dec 1 21:28:55 2022 -0500 analyzer: add test coverage for string ops gcc/testsuite/ChangeLog: * gcc.dg/analyzer/string-ops-concat-pair.c: New test. * gcc.dg/analyzer/string-ops-dup.c: New test. Signed-off-by: David Malcolm Diff: --- .../gcc.dg/analyzer/string-ops-concat-pair.c | 67 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c | 61 ++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c b/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c new file mode 100644 index 00000000000..f5bcd67594f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c @@ -0,0 +1,67 @@ +typedef __SIZE_TYPE__ size_t; +#define NULL ((void *)0) + +/* Concatenating a pair of strings. */ + +/* Correct but poor implementation with repeated __builtin_strlen calls. */ + +char * +alloc_dup_of_concatenated_pair_1_correct (const char *x, const char *y) +{ + size_t sz = __builtin_strlen (x) + __builtin_strlen (y) + 1; + char *result = __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, __builtin_strlen (x)); + __builtin_memcpy (result + __builtin_strlen (x), y, __builtin_strlen (y)); + result[__builtin_strlen(x) + __builtin_strlen (y)] = '\0'; + return result; +} + +/* Incorrect version: forgetting to add space for terminator. */ + +char * +alloc_dup_of_concatenated_pair_1_incorrect (const char *x, const char *y) +{ + /* Forgetting to add space for the terminator here. */ + size_t sz = __builtin_strlen (x) + __builtin_strlen (y); + char *result = __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, __builtin_strlen (x)); + __builtin_memcpy (result + __builtin_strlen (x), y, __builtin_strlen (y)); + result[__builtin_strlen(x) + __builtin_strlen (y)] = '\0'; /* { dg-warning "heap-based buffer overflow" "PR analyzer/105899" { xfail *-*-* } } */ + return result; +} + +/* As above, but only calling __builtin_strlen once on each input. */ + +char * +alloc_dup_of_concatenated_pair_2_correct (const char *x, const char *y) +{ + size_t len_x = __builtin_strlen (x); + size_t len_y = __builtin_strlen (y); + size_t sz = len_x + len_y + 1; + char *result = __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + __builtin_memcpy (result + len_x, y, len_y); + result[len_x + len_y] = '\0'; + return result; +} + +char * +alloc_dup_of_concatenated_pair_2_incorrect (const char *x, const char *y) +{ + size_t len_x = __builtin_strlen (x); + size_t len_y = __builtin_strlen (y); + size_t sz = len_x + len_y; /* Forgetting to add space for the terminator. */ + char *result = __builtin_malloc (sz); /* { dg-message "capacity: 'len_x \\+ len_y' bytes" } */ + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + __builtin_memcpy (result + len_x, y, len_y); + result[len_x + len_y] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ + return result; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c b/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c new file mode 100644 index 00000000000..44c4e9dc67e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c @@ -0,0 +1,61 @@ +typedef __SIZE_TYPE__ size_t; +#define NULL ((void *)0) + +/* Duplicating a string. */ + +/* Correct but poor implementation with repeated __builtin_strlen calls. */ + +char * +alloc_dup_1_correct (const char *x) +{ + size_t sz = __builtin_strlen (x) + 1; + char *result = __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, __builtin_strlen (x)); + result[__builtin_strlen(x)] = '\0'; + return result; +} + +/* Incorrect version: forgetting to add space for terminator. */ + +char * +alloc_dup_1_incorrect (const char *x, const char *y) +{ + /* Forgetting to add space for the terminator here. */ + size_t sz = __builtin_strlen (x) + 1; + char *result = __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, __builtin_strlen (x)); + result[__builtin_strlen(x)] = '\0'; /* { dg-warning "heap-based buffer overflow" "PR analyzer/105899" { xfail *-*-* } } */ + return result; +} + +/* As above, but only calling __builtin_strlen once. */ + +char * +alloc_dup_2_correct (const char *x) +{ + size_t len_x = __builtin_strlen (x); + size_t sz = len_x + 1; + char *result = __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + result[len_x] = '\0'; + return result; +} + +char * +alloc_dup_of_concatenated_pair_2_incorrect (const char *x, const char *y) +{ + size_t len_x = __builtin_strlen (x); + size_t sz = len_x; /* Forgetting to add space for the terminator. */ + char *result = __builtin_malloc (sz); /* { dg-message "capacity: 'len_x' bytes" } */ + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + result[len_x] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ + return result; +}