From 51f8b53adbd71a7ee727a500298245bca42b250b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 24 Mar 2024 16:07:43 +0100 Subject: [PATCH] added test to make sure `samples` produce the expected output / adjusted `samples` output and small cleanup (#6180) --- samples/arrayIndexOutOfBounds/out.txt | 3 -- .../bad.c | 0 .../good.c | 0 samples/arrayIndexOutOfBounds_1/out.txt | 3 ++ samples/arrayIndexOutOfBounds_2/bad.c | 8 ++++ samples/arrayIndexOutOfBounds_2/good.c | 8 ++++ samples/arrayIndexOutOfBounds_2/out.txt | 9 ++++ samples/bufferAccessOutOfBounds/bad.c | 9 ++-- samples/bufferAccessOutOfBounds/good.c | 9 ++-- samples/bufferAccessOutOfBounds/out.txt | 6 +-- samples/erase/out.txt | 24 ---------- samples/{erase => invalidContainer}/bad.cpp | 0 samples/{erase => invalidContainer}/good.cpp | 0 samples/invalidContainer/out.txt | 24 ++++++++++ samples/memleak/out.txt | 2 +- samples/outOfBounds/bad.c | 7 --- samples/outOfBounds/good.c | 7 --- samples/outOfBounds/out.txt | 3 -- samples/resourceLeak/bad.c | 2 +- test/cli/samples_test.py | 45 +++++++++++++++++++ 20 files changed, 110 insertions(+), 59 deletions(-) delete mode 100644 samples/arrayIndexOutOfBounds/out.txt rename samples/{arrayIndexOutOfBounds => arrayIndexOutOfBounds_1}/bad.c (100%) rename samples/{arrayIndexOutOfBounds => arrayIndexOutOfBounds_1}/good.c (100%) create mode 100644 samples/arrayIndexOutOfBounds_1/out.txt create mode 100644 samples/arrayIndexOutOfBounds_2/bad.c create mode 100644 samples/arrayIndexOutOfBounds_2/good.c create mode 100644 samples/arrayIndexOutOfBounds_2/out.txt delete mode 100644 samples/erase/out.txt rename samples/{erase => invalidContainer}/bad.cpp (100%) rename samples/{erase => invalidContainer}/good.cpp (100%) create mode 100644 samples/invalidContainer/out.txt delete mode 100644 samples/outOfBounds/bad.c delete mode 100644 samples/outOfBounds/good.c delete mode 100644 samples/outOfBounds/out.txt create mode 100644 test/cli/samples_test.py diff --git a/samples/arrayIndexOutOfBounds/out.txt b/samples/arrayIndexOutOfBounds/out.txt deleted file mode 100644 index bb8c14037bf..00000000000 --- a/samples/arrayIndexOutOfBounds/out.txt +++ /dev/null @@ -1,3 +0,0 @@ -samples\arrayIndexOutOfBounds\bad.c:7:6: error: Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds] - a[2] = 0; - ^ diff --git a/samples/arrayIndexOutOfBounds/bad.c b/samples/arrayIndexOutOfBounds_1/bad.c similarity index 100% rename from samples/arrayIndexOutOfBounds/bad.c rename to samples/arrayIndexOutOfBounds_1/bad.c diff --git a/samples/arrayIndexOutOfBounds/good.c b/samples/arrayIndexOutOfBounds_1/good.c similarity index 100% rename from samples/arrayIndexOutOfBounds/good.c rename to samples/arrayIndexOutOfBounds_1/good.c diff --git a/samples/arrayIndexOutOfBounds_1/out.txt b/samples/arrayIndexOutOfBounds_1/out.txt new file mode 100644 index 00000000000..c1ed04774d8 --- /dev/null +++ b/samples/arrayIndexOutOfBounds_1/out.txt @@ -0,0 +1,3 @@ +samples\arrayIndexOutOfBounds_1\bad.c:7:6: error: Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds] + a[2] = 0; + ^ diff --git a/samples/arrayIndexOutOfBounds_2/bad.c b/samples/arrayIndexOutOfBounds_2/bad.c new file mode 100644 index 00000000000..169a2d1dea3 --- /dev/null +++ b/samples/arrayIndexOutOfBounds_2/bad.c @@ -0,0 +1,8 @@ +int main() +{ + int a[2]; + int i; + for (i = 0; i < 3; i++) + a[i] = 0; + return a[0]; +} diff --git a/samples/arrayIndexOutOfBounds_2/good.c b/samples/arrayIndexOutOfBounds_2/good.c new file mode 100644 index 00000000000..62fa9eb55d2 --- /dev/null +++ b/samples/arrayIndexOutOfBounds_2/good.c @@ -0,0 +1,8 @@ +int main() +{ + int a[3]; + int i; + for (i = 0; i < 3; i++) + a[i] = 0; + return a[0]; +} diff --git a/samples/arrayIndexOutOfBounds_2/out.txt b/samples/arrayIndexOutOfBounds_2/out.txt new file mode 100644 index 00000000000..9fcc517dedd --- /dev/null +++ b/samples/arrayIndexOutOfBounds_2/out.txt @@ -0,0 +1,9 @@ +samples\arrayIndexOutOfBounds_2\bad.c:6:10: error: Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds] + a[i] = 0; + ^ +samples\arrayIndexOutOfBounds_2\bad.c:5:19: note: Assuming that condition 'i<3' is not redundant + for (i = 0; i < 3; i++) + ^ +samples\arrayIndexOutOfBounds_2\bad.c:6:10: note: Array index out of bounds + a[i] = 0; + ^ diff --git a/samples/bufferAccessOutOfBounds/bad.c b/samples/bufferAccessOutOfBounds/bad.c index 169a2d1dea3..e52bdb6a195 100644 --- a/samples/bufferAccessOutOfBounds/bad.c +++ b/samples/bufferAccessOutOfBounds/bad.c @@ -1,8 +1,7 @@ +#include int main() { - int a[2]; - int i; - for (i = 0; i < 3; i++) - a[i] = 0; - return a[0]; + char str[5]; + strcpy(str, "0123456789abcdef"); + return 0; } diff --git a/samples/bufferAccessOutOfBounds/good.c b/samples/bufferAccessOutOfBounds/good.c index 62fa9eb55d2..21bcabab1af 100644 --- a/samples/bufferAccessOutOfBounds/good.c +++ b/samples/bufferAccessOutOfBounds/good.c @@ -1,8 +1,7 @@ +#include int main() { - int a[3]; - int i; - for (i = 0; i < 3; i++) - a[i] = 0; - return a[0]; + char str[10]; + snprintf(str, 10, "%s", "abc"); + return 0; } diff --git a/samples/bufferAccessOutOfBounds/out.txt b/samples/bufferAccessOutOfBounds/out.txt index f166c371f0f..11c9d04a597 100644 --- a/samples/bufferAccessOutOfBounds/out.txt +++ b/samples/bufferAccessOutOfBounds/out.txt @@ -1,3 +1,3 @@ -samples\bufferAccessOutOfBounds\bad.c:6:10: error: Array 'a[2]' accessed at index 2, which is out of bounds. [arrayIndexOutOfBounds] - a[i] = 0; - ^ +samples\bufferAccessOutOfBounds\bad.c:5:12: error: Buffer is accessed out of bounds: str [bufferAccessOutOfBounds] + strcpy(str, "0123456789abcdef"); + ^ diff --git a/samples/erase/out.txt b/samples/erase/out.txt deleted file mode 100644 index d6f3852b657..00000000000 --- a/samples/erase/out.txt +++ /dev/null @@ -1,24 +0,0 @@ -samples\erase\bad.cpp:9:32: error: Using iterator to local container 'items' that may be invalid. [invalidContainer] - for (iter = items.begin(); iter != items.end(); ++iter) { - ^ -samples\erase\bad.cpp:9:17: note: Iterator to container is created here. - for (iter = items.begin(); iter != items.end(); ++iter) { - ^ -samples\erase\bad.cpp:10:19: note: Assuming condition is true. - if (*iter == 2) { - ^ -samples\erase\bad.cpp:10:19: note: Assuming condition is true. - if (*iter == 2) { - ^ -samples\erase\bad.cpp:9:37: note: Assuming condition is true. - for (iter = items.begin(); iter != items.end(); ++iter) { - ^ -samples\erase\bad.cpp:11:13: note: After calling 'erase', iterators or references to the container's data may be invalid . - items.erase(iter); - ^ -samples\erase\bad.cpp:4:22: note: Variable created here. - std::vector items; - ^ -samples\erase\bad.cpp:9:32: note: Using iterator to local container 'items' that may be invalid. - for (iter = items.begin(); iter != items.end(); ++iter) { - ^ diff --git a/samples/erase/bad.cpp b/samples/invalidContainer/bad.cpp similarity index 100% rename from samples/erase/bad.cpp rename to samples/invalidContainer/bad.cpp diff --git a/samples/erase/good.cpp b/samples/invalidContainer/good.cpp similarity index 100% rename from samples/erase/good.cpp rename to samples/invalidContainer/good.cpp diff --git a/samples/invalidContainer/out.txt b/samples/invalidContainer/out.txt new file mode 100644 index 00000000000..767cf898643 --- /dev/null +++ b/samples/invalidContainer/out.txt @@ -0,0 +1,24 @@ +samples\invalidContainer\bad.cpp:9:32: error: inconclusive: Using iterator to local container 'items' that may be invalid. [invalidContainer] + for (iter = items.begin(); iter != items.end(); ++iter) { + ^ +samples\invalidContainer\bad.cpp:9:28: note: Iterator to container is created here. + for (iter = items.begin(); iter != items.end(); ++iter) { + ^ +samples\invalidContainer\bad.cpp:10:19: note: Assuming condition is true. + if (*iter == 2) { + ^ +samples\invalidContainer\bad.cpp:10:19: note: Assuming condition is true. + if (*iter == 2) { + ^ +samples\invalidContainer\bad.cpp:9:37: note: Assuming condition is true. + for (iter = items.begin(); iter != items.end(); ++iter) { + ^ +samples\invalidContainer\bad.cpp:11:19: note: After calling 'erase', iterators or references to the container's data may be invalid . + items.erase(iter); + ^ +samples\invalidContainer\bad.cpp:4:22: note: Variable created here. + std::vector items; + ^ +samples\invalidContainer\bad.cpp:9:32: note: Using iterator to local container 'items' that may be invalid. + for (iter = items.begin(); iter != items.end(); ++iter) { + ^ diff --git a/samples/memleak/out.txt b/samples/memleak/out.txt index 263ac1b1a08..819ee8bf0d6 100644 --- a/samples/memleak/out.txt +++ b/samples/memleak/out.txt @@ -1,3 +1,3 @@ -samples/memleak/bad.c:8:5: error: Memory leak: a [memleak] +samples\memleak\bad.c:8:5: error: Memory leak: a [memleak] return result; ^ diff --git a/samples/outOfBounds/bad.c b/samples/outOfBounds/bad.c deleted file mode 100644 index e52bdb6a195..00000000000 --- a/samples/outOfBounds/bad.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -int main() -{ - char str[5]; - strcpy(str, "0123456789abcdef"); - return 0; -} diff --git a/samples/outOfBounds/good.c b/samples/outOfBounds/good.c deleted file mode 100644 index 21bcabab1af..00000000000 --- a/samples/outOfBounds/good.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -int main() -{ - char str[10]; - snprintf(str, 10, "%s", "abc"); - return 0; -} diff --git a/samples/outOfBounds/out.txt b/samples/outOfBounds/out.txt deleted file mode 100644 index 9ce3af4a5a8..00000000000 --- a/samples/outOfBounds/out.txt +++ /dev/null @@ -1,3 +0,0 @@ -samples\outOfBounds\bad.c:5:12: error: Buffer is accessed out of bounds: str [bufferAccessOutOfBounds] - strcpy(str, "0123456789abcdef"); - ^ diff --git a/samples/resourceLeak/bad.c b/samples/resourceLeak/bad.c index b517297a1b1..4595f10f4a4 100644 --- a/samples/resourceLeak/bad.c +++ b/samples/resourceLeak/bad.c @@ -1,7 +1,7 @@ #include int main() { - FILE *a = fopen("good.c", "r"); + const FILE *a = fopen("good.c", "r"); if (!a) return 0; diff --git a/test/cli/samples_test.py b/test/cli/samples_test.py new file mode 100644 index 00000000000..71848936e80 --- /dev/null +++ b/test/cli/samples_test.py @@ -0,0 +1,45 @@ +import os +import sys + +from testutils import cppcheck + +__script_dir = os.path.dirname(os.path.abspath(__file__)) +__root_dir = os.path.abspath(os.path.join(__script_dir, '..', '..')) + + +def test_samples(): + failures = {} + + samples_dir = os.path.join(__root_dir, 'samples') + for entry in os.listdir(samples_dir): + sample_dir = os.path.join(samples_dir, entry) + if not os.path.isdir(sample_dir): + continue + + with open(os.path.join(sample_dir, 'out.txt')) as out_in: + out_txt = out_in.read() + if not sys.platform == 'win32': + out_txt = out_txt.replace('\\', '/') + + if not os.path.exists(os.path.join(sample_dir, 'good.c')): + good_src = os.path.join('samples', entry, 'good.cpp') + bad_src = os.path.join('samples', entry, 'bad.cpp') + else: + good_src = os.path.join('samples', entry, 'good.c') + bad_src = os.path.join('samples', entry, 'bad.c') + + # check that good input does not produce any warnings + ret, stdout, stderr = cppcheck(['-q', '--enable=all', '--disable=missingInclude', '--inconclusive', '--check-level=exhaustive', '--error-exitcode=1', good_src], cwd=__root_dir) + if not ret == 0: + failures[good_src] = stderr + + # check that the bad inout produces a warning + ret, stdout, stderr = cppcheck(['-q', '--enable=all', '--disable=missingInclude', '--inconclusive', '--check-level=exhaustive', '--error-exitcode=1', bad_src], cwd=__root_dir) + if not ret == 1: + failures[bad_src] = stderr + + # check that the bad input procudes the expected output + if not stderr == out_txt: + failures[bad_src] = stderr + + assert failures == {}