diff options
author | David Malcolm <dmalcolm@redhat.com> | 2022-12-01 21:28:55 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2022-12-01 21:28:55 -0500 |
commit | 5cb7d28dcfb11a2810db55b0bbd71fe562bdc2a3 (patch) | |
tree | cd75a97e3306bfc173a7c48ad7bc9183b1e8023a /gcc | |
parent | e055e6db974d8b8950b30859a853e0aee74e20c2 (diff) | |
download | gcc-5cb7d28dcfb11a2810db55b0bbd71fe562bdc2a3.zip gcc-5cb7d28dcfb11a2810db55b0bbd71fe562bdc2a3.tar.gz gcc-5cb7d28dcfb11a2810db55b0bbd71fe562bdc2a3.tar.bz2 |
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 <dmalcolm@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c | 67 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c | 61 |
2 files changed, 128 insertions, 0 deletions
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 0000000..f5bcd67 --- /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 0000000..44c4e9d --- /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; +} |