From fb96e5433a7c1d8802ba2261b5f16f1f83301ec9 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 3 Dec 2019 18:49:11 +0100 Subject: [PATCH] y2038 addon: Fix that check can never return True, add tests (#2417) * y2038 addon: Fix that check can never return True, add tests At the beginning of `check_y2038_safe()` the variable `y2038safe` should be initialized with `True` and only be set to `False` if there are any issues. Otherwise it could never become `True`. In the unit tests the return value of `check_y2038_safe()` is now verified. But it does not yet work for the "good" example. The "good" example also returns `False` since it finds warnings in the include file. So this verification is marked with a "FIXME" comment. * y2038 tests: Add "good" test file that does not use time functionality The test file y2038-test-5-good-no-time-used.c does not use any time functionality so the y2038 addon is not allowed to issue any warnings and the check must return with `True` (code is safe). --- addons/test/test-y2038.py | 28 +++++++++++++++---- .../y2038/y2038-test-5-good-no-time-used.c | 14 ++++++++++ addons/y2038.py | 4 +-- 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 addons/test/y2038/y2038-test-5-good-no-time-used.c diff --git a/addons/test/test-y2038.py b/addons/test/test-y2038.py index caf009bbf..8beaa5ab9 100644 --- a/addons/test/test-y2038.py +++ b/addons/test/test-y2038.py @@ -18,7 +18,8 @@ from .util import dump_create, dump_remove, convert_json_output TEST_SOURCE_FILES = ['./addons/test/y2038/y2038-test-1-bad-time-bits.c', './addons/test/y2038/y2038-test-2-no-time-bits.c', './addons/test/y2038/y2038-test-3-no-use-time-bits.c', - './addons/test/y2038/y2038-test-4-good.c'] + './addons/test/y2038/y2038-test-4-good.c', + './addons/test/y2038/y2038-test-5-good-no-time-used.c'] def setup_module(module): @@ -34,7 +35,8 @@ def teardown_module(module): def test_1_bad_time_bits(capsys): - check_y2038_safe('./addons/test/y2038/y2038-test-1-bad-time-bits.c.dump', quiet=True) + is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-1-bad-time-bits.c.dump', quiet=True) + assert(is_safe is False) captured = capsys.readouterr() captured = captured.out.splitlines() json_output = convert_json_output(captured) @@ -50,7 +52,8 @@ def test_1_bad_time_bits(capsys): def test_2_no_time_bits(capsys): - check_y2038_safe('./addons/test/y2038/y2038-test-2-no-time-bits.c.dump', quiet=True) + is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-2-no-time-bits.c.dump', quiet=True) + assert(is_safe is False) captured = capsys.readouterr() captured = captured.out.splitlines() json_output = convert_json_output(captured) @@ -66,7 +69,8 @@ def test_2_no_time_bits(capsys): def test_3_no_use_time_bits(capsys): - check_y2038_safe('./addons/test/y2038/y2038-test-3-no-use-time-bits.c.dump', quiet=True) + is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-3-no-use-time-bits.c.dump', quiet=True) + assert(is_safe is False) captured = capsys.readouterr() captured = captured.out.splitlines() json_output = convert_json_output(captured) @@ -77,7 +81,8 @@ def test_3_no_use_time_bits(capsys): def test_4_good(capsys): - check_y2038_safe('./addons/test/y2038/y2038-test-4-good.c.dump', quiet=True) + is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-4-good.c.dump', quiet=True) + # assert(is_safe is True) # FIXME: This should be a "good" example returning "True" instead of "False" captured = capsys.readouterr() captured = captured.out.splitlines() json_output = convert_json_output(captured) @@ -88,6 +93,19 @@ def test_4_good(capsys): assert(len([c for c in unsafe_calls if c['file'].endswith('.c')]) == 0) +def test_5_good(capsys): + is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-5-good-no-time-used.c.dump', quiet=True) + assert(is_safe is True) + captured = capsys.readouterr() + captured = captured.out.splitlines() + json_output = convert_json_output(captured) + + # There are no warnings from C sources. + if 'unsafe-call' in json_output: + unsafe_calls = json_output['unsafe-call'] + assert(len([c for c in unsafe_calls if c['file'].endswith('.c')]) == 0) + + def test_arguments_regression(): args_ok = ["-t=foo", "--template=foo", "-q", "--quiet", diff --git a/addons/test/y2038/y2038-test-5-good-no-time-used.c b/addons/test/y2038/y2038-test-5-good-no-time-used.c new file mode 100644 index 000000000..4aedfcc25 --- /dev/null +++ b/addons/test/y2038/y2038-test-5-good-no-time-used.c @@ -0,0 +1,14 @@ +/* + * C file that does not use any time functionality -> no errors should + * be reported. + */ + +#include + +int main(int argc, char **argv) +{ + if (argc > 1) { + printf("Hello"); + } + return 0; +} diff --git a/addons/y2038.py b/addons/y2038.py index 4fd586f2e..d238ecd39 100755 --- a/addons/y2038.py +++ b/addons/y2038.py @@ -151,8 +151,8 @@ id_Y2038 = { def check_y2038_safe(dumpfile, quiet=False): - # at the start of the check, we don't know if code is Y2038 safe - y2038safe = False + # Assume that the code is Y2038 safe until proven otherwise + y2038safe = True # load XML from .dump file data = cppcheckdata.parsedump(dumpfile)