2020-01-20 18:53:40 +01:00
|
|
|
# Test if --bug-hunting works using the juliet testsuite
|
2019-10-24 21:48:34 +02:00
|
|
|
# The Juliet test suite can be downloaded from:
|
|
|
|
# https://samate.nist.gov/SRD/testsuite.php
|
2019-09-28 12:00:41 +02:00
|
|
|
|
|
|
|
import glob
|
|
|
|
import os
|
|
|
|
import re
|
2020-01-20 18:53:40 +01:00
|
|
|
import shutil
|
2019-09-28 12:00:41 +02:00
|
|
|
import sys
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
JULIET_PATH = os.path.expanduser('~/juliet')
|
2020-01-20 18:53:40 +01:00
|
|
|
if sys.argv[0] in ('test/bug-hunting/juliet.py', './test/bug-hunting/juliet.py'):
|
2019-09-29 08:26:09 +02:00
|
|
|
CPPCHECK_PATH = './cppcheck'
|
|
|
|
else:
|
|
|
|
CPPCHECK_PATH = '../../cppcheck'
|
2019-09-28 12:00:41 +02:00
|
|
|
|
2020-01-20 18:53:40 +01:00
|
|
|
RUN_CLANG = ('--clang' in sys.argv)
|
|
|
|
|
2019-09-28 19:28:12 +02:00
|
|
|
def get_files(juliet_path:str, test_cases:str):
|
2019-09-28 12:00:41 +02:00
|
|
|
ret = []
|
2019-09-28 19:28:12 +02:00
|
|
|
g = os.path.join(juliet_path, test_cases)
|
2019-09-28 12:00:41 +02:00
|
|
|
print(g)
|
|
|
|
for f in sorted(glob.glob(g)):
|
|
|
|
res = re.match(r'(.*[0-9][0-9])[a-x]?.(cp*)$', f)
|
|
|
|
if res is None:
|
|
|
|
print('Non-match!! ' + f)
|
|
|
|
sys.exit(1)
|
|
|
|
f = res.group(1) + '*.' + res.group(2)
|
|
|
|
if f not in ret:
|
|
|
|
ret.append(f)
|
|
|
|
return ret
|
|
|
|
|
2019-09-28 19:28:12 +02:00
|
|
|
|
|
|
|
def check(tc:str, warning_id:str):
|
|
|
|
num_ok = 0
|
|
|
|
num_failed = 0
|
|
|
|
|
|
|
|
for f in get_files(JULIET_PATH, tc):
|
|
|
|
cmd = [CPPCHECK_PATH,
|
|
|
|
'-I' + os.path.join(JULIET_PATH, 'C/testcasesupport'),
|
|
|
|
'-DOMIT_GOOD',
|
2019-10-23 16:49:45 +02:00
|
|
|
'-DAF_INET=1',
|
|
|
|
'-DINADDR_ANY=1',
|
2019-09-28 19:28:12 +02:00
|
|
|
'--library=posix',
|
2020-01-15 21:06:00 +01:00
|
|
|
'--bug-hunting',
|
2019-09-28 19:28:12 +02:00
|
|
|
'--platform=unix64']
|
2020-01-20 18:53:40 +01:00
|
|
|
if RUN_CLANG:
|
|
|
|
cmd += ['--clang', '--cppcheck-build-dir=juliet-build-dir']
|
|
|
|
if not os.path.isdir('juliet-build-dir'):
|
|
|
|
os.mkdir('juliet-build-dir')
|
2019-09-28 19:28:12 +02:00
|
|
|
cmd += glob.glob(f)
|
|
|
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
comm = p.communicate()
|
|
|
|
stdout = comm[0].decode(encoding='utf-8', errors='ignore')
|
|
|
|
stderr = comm[1].decode(encoding='utf-8', errors='ignore')
|
2020-01-20 18:53:40 +01:00
|
|
|
if RUN_CLANG:
|
|
|
|
shutil.rmtree('juliet-build-dir')
|
2019-09-28 19:28:12 +02:00
|
|
|
|
|
|
|
if warning_id in stderr:
|
|
|
|
num_ok += 1
|
|
|
|
else:
|
2020-05-07 18:55:22 +02:00
|
|
|
print('fail: ' + ' '.join(cmd))
|
2019-09-28 19:28:12 +02:00
|
|
|
num_failed += 1
|
|
|
|
|
|
|
|
cwepos = tc.find('CWE')
|
|
|
|
cwe = tc[cwepos:cwepos+6]
|
|
|
|
|
2020-05-07 18:55:22 +02:00
|
|
|
print('%s ok:%i, fail:%i' % (cwe, num_ok, num_failed))
|
|
|
|
if num_failed != 0:
|
|
|
|
sys.exit(1)
|
2019-09-28 19:28:12 +02:00
|
|
|
|
|
|
|
|
2020-05-07 18:55:22 +02:00
|
|
|
check('C/testcases/CWE369_Divide_by_Zero/s*/*.c', 'bughuntingDivByZero')
|
2020-06-28 08:16:46 +02:00
|
|
|
#check('C/testcases/CWE457_Use_of_Uninitialized_Variable/s*/*.c', 'bughuntingUninit')
|
2019-09-28 19:28:12 +02:00
|
|
|
|
2019-09-28 12:00:41 +02:00
|
|
|
|