diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/coccinelle/ceil_div.cocci | 6 | ||||
-rwxr-xr-x | scripts/coccinelle/test-operator-cleanup | 11 | ||||
-rw-r--r-- | scripts/coccinelle/test_assert_int.cocci | 49 | ||||
-rw-r--r-- | scripts/coccinelle/test_assert_null.cocci | 11 | ||||
-rw-r--r-- | scripts/coccinelle/test_assert_zero.cocci | 5 | ||||
-rwxr-xr-x | scripts/codegen/fuzzing_include_am.py | 9 | ||||
-rwxr-xr-x | scripts/maint/annotate_ifdef_directives | 74 | ||||
-rwxr-xr-x | scripts/maint/checkSpace.pl | 6 | ||||
-rwxr-xr-x | scripts/maint/lintChanges.py | 67 | ||||
-rwxr-xr-x | scripts/maint/run_calltool.sh | 29 | ||||
-rwxr-xr-x | scripts/test/cov-diff | 10 | ||||
-rwxr-xr-x | scripts/test/coverage | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | scripts/test/scan-build.sh | 61 |
13 files changed, 303 insertions, 37 deletions
diff --git a/scripts/coccinelle/ceil_div.cocci b/scripts/coccinelle/ceil_div.cocci new file mode 100644 index 0000000000..00843e82c3 --- /dev/null +++ b/scripts/coccinelle/ceil_div.cocci @@ -0,0 +1,6 @@ +@@ +expression n, d; +@@ + +- (((n) + (d) - 1) / (d)) ++ CEIL_DIV(n, d) diff --git a/scripts/coccinelle/test-operator-cleanup b/scripts/coccinelle/test-operator-cleanup new file mode 100755 index 0000000000..e7822542a4 --- /dev/null +++ b/scripts/coccinelle/test-operator-cleanup @@ -0,0 +1,11 @@ +#!/usr/bin/perl -w -p -i + +next if m#^ */\*# or m#^ *\* #; + +s/<([,)])/OP_LT$1/; +s/(?<=[\s,])>([,)])/OP_GT$1/; +#s/>([,)])/OP_GT$1/; +s/==([,)])/OP_EQ$1/; +s/>=([,)])/OP_GE$1/; +s/<=([,)])/OP_LE$1/; +s/!=([,)])/OP_NE$1/; diff --git a/scripts/coccinelle/test_assert_int.cocci b/scripts/coccinelle/test_assert_int.cocci new file mode 100644 index 0000000000..80e86b4f3c --- /dev/null +++ b/scripts/coccinelle/test_assert_int.cocci @@ -0,0 +1,49 @@ +@@ +int e; +constant c; +@@ + +( +- tt_assert(e == c) ++ tt_int_op(e, OP_EQ, c) +| +- tt_assert(e != c) ++ tt_int_op(e, OP_NE, c) +| +- tt_assert(e < c) ++ tt_int_op(e, OP_LT, c) +| +- tt_assert(e <= c) ++ tt_int_op(e, OP_LE, c) +| +- tt_assert(e > c) ++ tt_int_op(e, OP_GT, c) +| +- tt_assert(e >= c) ++ tt_int_op(e, OP_GE, c) +) + +@@ +unsigned int e; +constant c; +@@ + +( +- tt_assert(e == c) ++ tt_uint_op(e, OP_EQ, c) +| +- tt_assert(e != c) ++ tt_uint_op(e, OP_NE, c) +| +- tt_assert(e < c) ++ tt_uint_op(e, OP_LT, c) +| +- tt_assert(e <= c) ++ tt_uint_op(e, OP_LE, c) +| +- tt_assert(e > c) ++ tt_uint_op(e, OP_GT, c) +| +- tt_assert(e >= c) ++ tt_uint_op(e, OP_GE, c) +) diff --git a/scripts/coccinelle/test_assert_null.cocci b/scripts/coccinelle/test_assert_null.cocci new file mode 100644 index 0000000000..3d66e1ee0b --- /dev/null +++ b/scripts/coccinelle/test_assert_null.cocci @@ -0,0 +1,11 @@ +@@ +expression * e; +@@ + +( +- tt_assert(e != NULL) ++ tt_ptr_op(e, OP_NE, NULL) +| +- tt_assert(e == NULL) ++ tt_ptr_op(e, OP_EQ, NULL) +) diff --git a/scripts/coccinelle/test_assert_zero.cocci b/scripts/coccinelle/test_assert_zero.cocci new file mode 100644 index 0000000000..09feaa5fb4 --- /dev/null +++ b/scripts/coccinelle/test_assert_zero.cocci @@ -0,0 +1,5 @@ +@@ +@@ + +- tt_assert(0) ++ tt_abort() diff --git a/scripts/codegen/fuzzing_include_am.py b/scripts/codegen/fuzzing_include_am.py index 6e45c21926..fee6d4494a 100755 --- a/scripts/codegen/fuzzing_include_am.py +++ b/scripts/codegen/fuzzing_include_am.py @@ -7,7 +7,9 @@ FUZZERS = """ diff-apply extrainfo hsdescv2 + hsdescv3 http + http-connect iptsv2 microdesc vrs @@ -30,13 +32,14 @@ FUZZING_LIBS = \ src/common/libor-ctime-testing.a \ src/common/libor-event-testing.a \ src/trunnel/libor-trunnel-testing.a \ + $(rust_ldadd) \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \ @TOR_LIBEVENT_LIBS@ \ - @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \ + @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \ + @CURVE25519_LIBS@ \ @TOR_SYSTEMD_LIBS@ \ @TOR_LZMA_LIBS@ \ - @TOR_ZSTD_LIBS@ \ - $(rust_ldadd) + @TOR_ZSTD_LIBS@ oss-fuzz-prereqs: \ src/or/libtor-testing.a \ diff --git a/scripts/maint/annotate_ifdef_directives b/scripts/maint/annotate_ifdef_directives new file mode 100755 index 0000000000..368d842e2e --- /dev/null +++ b/scripts/maint/annotate_ifdef_directives @@ -0,0 +1,74 @@ +#!/usr/bin/python +# Copyright (c) 2017, The Tor Project, Inc. +# See LICENSE for licensing information + +import re + +LINE_OBVIOUSNESS_LIMIT = 4 + +class Problem(Exception): + pass + +def uncomment(s): + s = re.sub(r'//.*','',s) + s = re.sub(r'/\*.*','',s) + return s.strip() + +def translate(f_in, f_out): + whole_file = [] + stack = [] + cur_level = whole_file + lineno = 0 + for line in f_in: + lineno += 1 + m = re.match(r'\s*#\s*(if|ifdef|ifndef|else|endif|elif)\b\s*(.*)', + line) + if not m: + f_out.write(line) + continue + command,rest = m.groups() + if command in ("if", "ifdef", "ifndef"): + # The #if directive pushes us one level lower on the stack. + if command == 'ifdef': + rest = "defined(%s)"%uncomment(rest) + elif command == 'ifndef': + rest = "!defined(%s)"%uncomment(rest) + elif rest.endswith("\\"): + rest = rest[:-1]+"..." + + rest = uncomment(rest) + + new_level = [ (command, rest, lineno) ] + stack.append(cur_level) + cur_level = new_level + f_out.write(line) + elif command in ("else", "elif"): + if len(cur_level) == 0 or cur_level[-1][0] == 'else': + raise Problem("Unexpected #%s on %d"% (command,lineno)) + if (len(cur_level) == 1 and command == 'else' and + lineno > cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT): + f_out.write("#else /* !(%s) */\n"%cur_level[0][1]) + else: + f_out.write(line) + cur_level.append((command, rest, lineno)) + else: + assert command == 'endif' + if len(stack) == 0: + raise Problem("Unmatched #%s on %s"% (command,lineno)) + if lineno <= cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT: + f_out.write(line) + elif len(cur_level) == 1 or ( + len(cur_level) == 2 and cur_level[1][0] == 'else'): + f_out.write("#endif /* %s */\n"%cur_level[0][1]) + else: + f_out.write("#endif /* %s || ... */\n"%cur_level[0][1]) + cur_level = stack.pop() + if len(stack) or cur_level != whole_file: + raise Problem("Missing #endif") + +import sys,os +for fn in sys.argv[1:]: + with open(fn+"_OUT", 'w') as output_file: + translate(open(fn, 'r'), output_file) + os.rename(fn+"_OUT", fn) + diff --git a/scripts/maint/checkSpace.pl b/scripts/maint/checkSpace.pl index 3043eb1aaf..a12370f21f 100755 --- a/scripts/maint/checkSpace.pl +++ b/scripts/maint/checkSpace.pl @@ -123,6 +123,10 @@ for my $fn (@ARGV) { if (/([^\s'])\{/) { msg " $1\{:$fn:$.\n"; } + ## Warn about double semi-colons at the end of a line. + if (/;;$/) { + msg " double semi-colons at the end of $. in $fn\n" + } ## Warn about multiple internal spaces. #if (/[^\s,:]\s{2,}[^\s\\=]/) { # msg " X X:$fn:$.\n"; @@ -140,7 +144,7 @@ for my $fn (@ARGV) { $1 ne "switch" and $1 ne "return" and $1 ne "int" and $1 ne "elsif" and $1 ne "WINAPI" and $2 ne "WINAPI" and $1 ne "void" and $1 ne "__attribute__" and $1 ne "op" and - $1 ne "size_t" and $1 ne "double" and + $1 ne "size_t" and $1 ne "double" and $1 ne "uint64_t" and $1 ne "workqueue_reply_t") { msg " fn ():$fn:$.\n"; } diff --git a/scripts/maint/lintChanges.py b/scripts/maint/lintChanges.py index bf06064fa8..d5b8fcae5c 100755 --- a/scripts/maint/lintChanges.py +++ b/scripts/maint/lintChanges.py @@ -20,8 +20,20 @@ KNOWN_GROUPS = set([ "Testing", "Documentation", "Code simplification and refactoring", - "Removed features"]) + "Removed features", + "Deprecated features", + "Directory authority changes"]) +NEEDS_SUBCATEGORIES = set([ + "Minor bugfix", + "Minor bugfixes", + "Major bugfix", + "Major bugfixes", + "Minor feature", + "Minor features", + "Major feature", + "Major features", + ]) def lintfile(fname): have_warned = [] @@ -46,13 +58,11 @@ def lintfile(fname): m = re.match(r'^[ ]{2}o ([^\(:]*)([^:]*):', contents) if not m: - warn("header not in format expected") + warn("Header not in format expected. (' o Foo:' or ' o Foo (Bar):')") elif m.group(1).strip() not in KNOWN_GROUPS: - warn("Weird header: %r" % m.group(1)) - elif (("bugfix" in m.group(1) or "feature" in m.group(1)) and - ("Removed" not in m.group(1)) and - '(' not in m.group(2)): - warn("Missing subcategory on %s" % m.group(1)) + warn("Unrecognized header: %r" % m.group(1)) + elif (m.group(1) in NEEDS_SUBCATEGORIES and '(' not in m.group(2)): + warn("Missing subcategory on %r" % m.group(1)) if m: isBug = ("bug" in m.group(1).lower() or "fix" in m.group(1).lower()) @@ -62,25 +72,46 @@ def lintfile(fname): contents = " ".join(contents.split()) if re.search(r'\#\d{2,}', contents): - warn("don't use a # before ticket numbers") + warn("Don't use a # before ticket numbers. ('bug 1234' not '#1234')") if isBug and not re.search(r'(\d+)', contents): - warn("bugfix does not mention a number") - elif isBug and not re.search(r'Fixes ([a-z ]*)bug (\d+)', contents): - warn("bugfix does not say 'Fixes bug XXX'") + warn("Ticket marked as bugfix, but does not mention a number.") + elif isBug and not re.search(r'Fixes ([a-z ]*)bugs? (\d+)', contents): + warn("Ticket marked as bugfix, but does not say 'Fixes bug XXX'") if re.search(r'[bB]ug (\d+)', contents): if not re.search(r'[Bb]ugfix on ', contents): - warn("bugfix does not say 'bugfix on X.Y.Z'") - elif not re.search('[fF]ixes ([a-z ]*)bug (\d+); bugfix on ', + warn("Bugfix does not say 'bugfix on X.Y.Z'") + elif not re.search('[fF]ixes ([a-z ]*)bugs? (\d+)((, \d+)* and \d+)?; bugfix on ', contents): - warn("bugfix incant is not semicoloned") + warn("Bugfix does not say 'Fixes bug X; bugfix on Y'") elif re.search('tor-([0-9]+)', contents): - warn("do not prefix versions with 'tor-'") - + warn("Do not prefix versions with 'tor-'. ('0.1.2', not 'tor-0.1.2'.)") + + return have_warned != [] + +def files(args): + """Walk through the arguments: for directories, yield their contents; + for files, just yield the files. Only search one level deep, because + that's how the changes directory is laid out.""" + for f in args: + if os.path.isdir(f): + for item in os.listdir(f): + if item.startswith("."): #ignore dotfiles + continue + yield os.path.join(f, item) + else: + yield f if __name__ == '__main__': - for fname in sys.argv[1:]: + problems = 0 + for fname in files(sys.argv[1:]): if fname.endswith("~"): continue - lintfile(fname) + if lintfile(fname): + problems += 1 + + if problems: + sys.exit(1) + else: + sys.exit(0) diff --git a/scripts/maint/run_calltool.sh b/scripts/maint/run_calltool.sh new file mode 100755 index 0000000000..efb8706fea --- /dev/null +++ b/scripts/maint/run_calltool.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +# You can find calltool at https://gitweb.torproject.org/user/nickm/calltool.git + +set -e + +if test "x$CALLTOOL_PATH" != "x"; then + PYTHONPATH="${CALLTOOL_PATH}:${PYTHONPATH}" + export PYTHONPATH +fi + +mkdir -p callgraph + +SUBITEMS="fn_graph fn_invgraph fn_scc fn_scc_weaklinks module_graph module_invgraph module_scc module_scc_weaklinks" + +for calculation in $SUBITEMS; do + echo "======== $calculation" + python -m calltool $calculation > callgraph/$calculation +done + +echo <<EOF > callgraph/README +This directory holds output from calltool, as run on Tor. For more +information about each of these files, see the NOTES and README files in +the calltool distribution. + +You can find calltool at + https://gitweb.torproject.org/user/nickm/calltool.git +EOF + diff --git a/scripts/test/cov-diff b/scripts/test/cov-diff index 7da7f0be9d..ed8874d2d3 100755 --- a/scripts/test/cov-diff +++ b/scripts/test/cov-diff @@ -7,9 +7,13 @@ DIRA="$1" DIRB="$2" -for A in $DIRA/*; do - B=$DIRB/`basename $A` - perl -pe 's/^\s*\!*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$A" > "$A.tmp" +for B in $DIRB/*; do + A=$DIRA/`basename $B` + if [ -f $A ]; then + perl -pe 's/^\s*\!*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$A" > "$A.tmp" + else + cat /dev/null > "$A.tmp" + fi perl -pe 's/^\s*\!*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$B" > "$B.tmp" diff -u "$A.tmp" "$B.tmp" rm "$A.tmp" "$B.tmp" diff --git a/scripts/test/coverage b/scripts/test/coverage index f4ae475828..f10c5afaae 100755 --- a/scripts/test/coverage +++ b/scripts/test/coverage @@ -29,7 +29,7 @@ for fn in src/or/*.c src/common/*.c; do gcov -o $on $fn if [ -e $GC ] then - if [ -n $dst ] + if [ -d "$dst" ] then mv $GC $dst/$GC fi diff --git a/scripts/test/scan-build.sh b/scripts/test/scan-build.sh index 36e69e6d00..793adf87e2 100644..100755 --- a/scripts/test/scan-build.sh +++ b/scripts/test/scan-build.sh @@ -5,37 +5,76 @@ # This script is used for running a bunch of clang scan-build checkers # on Tor. +# These don't seem to cause false positives in our code, so let's turn +# them on. CHECKERS="\ - -disable-checker deadcode.DeadStores \ - -enable-checker alpha.core.CastSize \ + -enable-checker alpha.core.CallAndMessageUnInitRefArg \ -enable-checker alpha.core.CastToStruct \ + -enable-checker alpha.core.Conversion \ + -enable-checker alpha.core.FixedAddr \ -enable-checker alpha.core.IdenticalExpr \ + -enable-checker alpha.core.PointerArithm \ -enable-checker alpha.core.SizeofPtr \ - -enable-checker alpha.security.ArrayBoundV2 \ + -enable-checker alpha.core.TestAfterDivZero \ -enable-checker alpha.security.MallocOverflow \ -enable-checker alpha.security.ReturnPtrRange \ - -enable-checker alpha.unix.SimpleStream + -enable-checker alpha.unix.BlockInCriticalSection \ + -enable-checker alpha.unix.Chroot \ + -enable-checker alpha.unix.PthreadLock \ + -enable-checker alpha.unix.PthreadLock \ + -enable-checker alpha.unix.SimpleStream \ + -enable-checker alpha.unix.Stream \ -enable-checker alpha.unix.cstring.BufferOverlap \ -enable-checker alpha.unix.cstring.NotNullTerminated \ - -enable-checker alpha.unix.cstring.OutOfBounds \ - -enable-checker alpha.core.FixedAddr \ + -enable-checker alpha.valist.CopyToSelf \ + -enable-checker alpha.valist.Uninitialized \ + -enable-checker alpha.valist.Unterminated \ + -enable-checker security.FloatLoopCounter \ -enable-checker security.insecureAPI.strcpy \ - -enable-checker alpha.unix.PthreadLock \ - -enable-checker alpha.core.PointerArithm \ - -enable-checker alpha.core.TestAfterDivZero \ " +# These have high false-positive rates. +EXTRA_CHECKERS="\ + -enable-checker alpha.security.ArrayBoundV2 \ + -enable-checker alpha.unix.cstring.OutOfBounds \ + -enable-checker alpha.core.CastSize \ +" + +# These don't seem to generate anything useful +NOISY_CHECKERS="\ + -enable-checker alpha.clone.CloneChecker \ + -enable-checker alpha.deadcode.UnreachableCode \ +" + +if test "x$SCAN_BUILD_OUTPUT" != "x"; then + OUTPUTARG="-o $SCAN_BUILD_OUTPUT" +else + OUTPUTARG="" +fi + scan-build \ $CHECKERS \ ./configure scan-build \ + make clean + +# Make this not get scanned for dead assignments, since it has lots of +# dead assignments we don't care about. +scan-build \ $CHECKERS \ - make -j2 -k + -disable-checker deadcode.DeadStores \ + make -j5 -k ./src/ext/ed25519/ref10/libed25519_ref10.a +scan-build \ + $CHECKERS $OUTPUTARG \ + make -j5 -k + +CHECKERS="\ +" # This one gives a false positive on every strcmp. # -enable-checker alpha.core.PointerSub # Needs work -# alpha.unix.MallocWithAnnotations ?? +# -enable-checker alpha.unix.MallocWithAnnotations |