From d80a217f7f20c8af38f938a85dd62f1809c09709 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Wed, 1 Mar 2017 14:49:58 +0100 Subject: [PATCH] contrib: add script to find unterminated value_string arrays Unterminated value_string arrays are dangerous since get_value_string() and get_string_value() need to know where the struct ends. If the terminator is missing, they might run through and return arbitrary memory locations. Employ some regexes to find such unterminated value string arrays and return nonzero if any are found. This can be used in our jenkins build jobs to avoid committing unterminated value_string arrays. In fact I've found one in current libosmocore: gsm0808_bssap_names in gsm/gsm0808.c, fixed in a separate patch. Change-Id: I2bc93ab4781487e7685cfb63091a489cd126b1a8 --- ...rify_value_string_arrays_are_terminated.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100755 contrib/verify_value_string_arrays_are_terminated.py diff --git a/contrib/verify_value_string_arrays_are_terminated.py b/contrib/verify_value_string_arrays_are_terminated.py new file mode 100755 index 000000000..020bb4dd4 --- /dev/null +++ b/contrib/verify_value_string_arrays_are_terminated.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +# vim: expandtab tabstop=2 shiftwidth=2 nocin + +''' +Usage: + verify_value_string_arrays_are_terminated.py PATH [PATH [...]] + +e.g. +libosmocore/contrib/verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]") +''' + +import re +import sys +import codecs + +value_string_array_re = re.compile( + r'((\bstruct\s+value_string\b[^{;]*?)\s*=[^{;]*{[^;]*}\s*;)', + re.MULTILINE | re.DOTALL) + +members = r'(\.(value|str)\s*=\s*)?' +terminator_re = re.compile('{\s*' + members + '(0|NULL)\s*,' + '\s*' + members + '(0|NULL)\s*}') +errors_found = 0 + +for f in sys.argv[1:]: + arrays = value_string_array_re.findall(codecs.open(f, "r", "utf-8").read()) + for array_def, name in arrays: + if not terminator_re.search(array_def): + print('ERROR: file contains unterminated value_string %r: %r' + % (name, f)) + errors_found += 1 + +sys.exit(errors_found)