diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/coccinelle/debugmm.cocci | 29 | ||||
-rwxr-xr-x | scripts/git/git-merge-forward.sh | 12 | ||||
-rwxr-xr-x | scripts/git/git-pull-all.sh | 7 | ||||
-rwxr-xr-x | scripts/git/git-push-all.sh | 5 | ||||
-rwxr-xr-x | scripts/maint/annotate_ifdef_directives | 74 | ||||
-rwxr-xr-x | scripts/maint/annotate_ifdef_directives.py | 317 | ||||
-rw-r--r-- | scripts/maint/practracker/exceptions.txt | 58 | ||||
-rwxr-xr-x | scripts/maint/practracker/practracker.py | 13 | ||||
-rw-r--r-- | scripts/maint/practracker/problem.py | 6 | ||||
-rwxr-xr-x | scripts/maint/practracker/test_practracker.sh | 6 | ||||
-rw-r--r-- | scripts/maint/practracker/testdata/ex1-overbroad-expected.txt | 2 | ||||
-rw-r--r-- | scripts/maint/practracker/testdata/ex1.txt | 5 | ||||
-rw-r--r-- | scripts/maint/practracker/util.py | 7 |
13 files changed, 432 insertions, 109 deletions
diff --git a/scripts/coccinelle/debugmm.cocci b/scripts/coccinelle/debugmm.cocci new file mode 100644 index 0000000000..dbd308df33 --- /dev/null +++ b/scripts/coccinelle/debugmm.cocci @@ -0,0 +1,29 @@ +// Look for use of expressions with side-effects inside of debug logs. +// +// This script detects expressions like ++E, --E, E++, and E-- inside of +// calls to log_debug(). +// +// The log_debug() macro exits early if debug logging is not enabled, +// potentially causing problems if its arguments have side-effects. + +@@ +expression E; +@@ +*log_debug(... , <+... --E ...+>, ... ); + + +@@ +expression E; +@@ +*log_debug(... , <+... ++E ...+>, ... ); + +@@ +expression E; +@@ +*log_debug(... , <+... E-- ...+>, ... ); + + +@@ +expression E; +@@ +*log_debug(... , <+... E++ ...+>, ... ); diff --git a/scripts/git/git-merge-forward.sh b/scripts/git/git-merge-forward.sh index e481b40975..d16519b3f5 100755 --- a/scripts/git/git-merge-forward.sh +++ b/scripts/git/git-merge-forward.sh @@ -98,13 +98,16 @@ MAINT_040=( "maint-0.4.0" "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.0" \ "_040" "_035") MAINT_041=( "maint-0.4.1" "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.1" \ "_041" "_040") -MAINT_MASTER=( "master" "maint-0.4.1" "$GIT_PATH/$TOR_MASTER_NAME" \ +MAINT_042=( "maint-0.4.2" "maint-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.2" \ + "_042" "_041") +MAINT_MASTER=( "master" "maint-0.4.2" "$GIT_PATH/$TOR_MASTER_NAME" \ "_master" "_041") RELEASE_029=( "release-0.2.9" "maint-0.2.9" "$GIT_PATH/$TOR_WKT_NAME/release-0.2.9" ) RELEASE_035=( "release-0.3.5" "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/release-0.3.5" ) RELEASE_040=( "release-0.4.0" "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.0" ) RELEASE_041=( "release-0.4.1" "maint-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.1" ) +RELEASE_042=( "release-0.4.2" "maint-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.2" ) # The master branch path has to be the main repository thus contains the # origin that will be used to fetch the updates. All the worktrees are created @@ -117,11 +120,13 @@ ${MAINT_029_TB[0]} ${MAINT_035[0]} ${MAINT_040[0]} ${MAINT_041[0]} +${MAINT_042[0]} ${MAINT_MASTER[0]} ${RELEASE_029[0]} ${RELEASE_035[0]} ${RELEASE_040[0]} ${RELEASE_041[0]} +${RELEASE_042[0]} EOF ####################### @@ -186,6 +191,9 @@ if [ -z "$TEST_BRANCH_PREFIX" ]; then MAINT_041[@] RELEASE_041[@] + MAINT_042[@] + RELEASE_042[@] + MAINT_MASTER[@] ) @@ -201,6 +209,8 @@ else MAINT_041[@] + MAINT_042[@] + MAINT_MASTER[@] ) diff --git a/scripts/git/git-pull-all.sh b/scripts/git/git-pull-all.sh index 0d6daf432d..773f97b42b 100755 --- a/scripts/git/git-pull-all.sh +++ b/scripts/git/git-pull-all.sh @@ -62,12 +62,14 @@ MAINT_029=( "maint-0.2.9" "$GIT_PATH/$TOR_WKT_NAME/maint-0.2.9" ) MAINT_035=( "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/maint-0.3.5" ) MAINT_040=( "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.0" ) MAINT_041=( "maint-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.1" ) +MAINT_042=( "maint-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.2" ) MAINT_MASTER=( "master" "$GIT_PATH/$TOR_MASTER_NAME" ) RELEASE_029=( "release-0.2.9" "$GIT_PATH/$TOR_WKT_NAME/release-0.2.9" ) RELEASE_035=( "release-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/release-0.3.5" ) RELEASE_040=( "release-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.0" ) RELEASE_041=( "release-0.4.1" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.1" ) +RELEASE_042=( "release-0.4.2" "$GIT_PATH/$TOR_WKT_NAME/release-0.4.2" ) # The master branch path has to be the main repository thus contains the # origin that will be used to fetch the updates. All the worktrees are created @@ -80,11 +82,13 @@ ${MAINT_029[0]} ${MAINT_035[0]} ${MAINT_040[0]} ${MAINT_041[0]} +${MAINT_042[0]} ${MAINT_MASTER[0]} ${RELEASE_029[0]} ${RELEASE_035[0]} ${RELEASE_040[0]} ${RELEASE_041[0]} +${RELEASE_042[0]} EOF ########################### @@ -106,6 +110,9 @@ WORKTREE=( MAINT_041[@] RELEASE_041[@] + MAINT_042[@] + RELEASE_042[@] + MAINT_MASTER[@] ) COUNT=${#WORKTREE[@]} diff --git a/scripts/git/git-push-all.sh b/scripts/git/git-push-all.sh index a388f01564..f848da7841 100755 --- a/scripts/git/git-push-all.sh +++ b/scripts/git/git-push-all.sh @@ -167,6 +167,7 @@ DEFAULT_UPSTREAM_BRANCHES= if [ "$DEFAULT_UPSTREAM_REMOTE" != "$UPSTREAM_REMOTE" ]; then DEFAULT_UPSTREAM_BRANCHES=$(echo \ "$DEFAULT_UPSTREAM_REMOTE"/master \ + "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.2 \ "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.1 \ "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.0 \ "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.3.5 \ @@ -176,6 +177,7 @@ fi UPSTREAM_BRANCHES=$(echo \ "$UPSTREAM_REMOTE"/master \ + "$UPSTREAM_REMOTE"/{release,maint}-0.4.2 \ "$UPSTREAM_REMOTE"/{release,maint}-0.4.1 \ "$UPSTREAM_REMOTE"/{release,maint}-0.4.0 \ "$UPSTREAM_REMOTE"/{release,maint}-0.3.5 \ @@ -188,6 +190,7 @@ UPSTREAM_BRANCHES=$(echo \ PUSH_BRANCHES=$(echo \ master \ + {release,maint}-0.4.2 \ {release,maint}-0.4.1 \ {release,maint}-0.4.0 \ {release,maint}-0.3.5 \ @@ -201,6 +204,7 @@ if [ -z "$TEST_BRANCH_PREFIX" ]; then # List of branches to push. Ordering is not important. PUSH_BRANCHES=$(echo \ master \ + {release,maint}-0.4.2 \ {release,maint}-0.4.1 \ {release,maint}-0.4.0 \ {release,maint}-0.3.5 \ @@ -213,6 +217,7 @@ else # List of branches to push. Ordering is not important. PUSH_BRANCHES=" \ ${TEST_BRANCH_PREFIX}_master \ + ${TEST_BRANCH_PREFIX}_042 \ ${TEST_BRANCH_PREFIX}_041 \ ${TEST_BRANCH_PREFIX}_040 \ ${TEST_BRANCH_PREFIX}_035 \ diff --git a/scripts/maint/annotate_ifdef_directives b/scripts/maint/annotate_ifdef_directives deleted file mode 100755 index ca267a865e..0000000000 --- a/scripts/maint/annotate_ifdef_directives +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2017-2019, 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/annotate_ifdef_directives.py b/scripts/maint/annotate_ifdef_directives.py new file mode 100755 index 0000000000..102128bfa0 --- /dev/null +++ b/scripts/maint/annotate_ifdef_directives.py @@ -0,0 +1,317 @@ +#!/usr/bin/python +# Copyright (c) 2017-2019, The Tor Project, Inc. +# See LICENSE for licensing information + +r""" +This script iterates over a list of C files. For each file, it looks at the +#if/#else C macros, and annotates them with comments explaining what they +match. + +For example, it replaces this kind of input... + +>>> INPUT = ''' +... #ifdef HAVE_OCELOT +... C code here +... #if MIMSY == BOROGROVE +... block 1 +... block 1 +... block 1 +... block 1 +... #else +... block 2 +... block 2 +... block 2 +... block 2 +... #endif +... #endif +... ''' + +With this kind of output: +>>> EXPECTED_OUTPUT = ''' +... #ifdef HAVE_OCELOT +... C code here +... #if MIMSY == BOROGROVE +... block 1 +... block 1 +... block 1 +... block 1 +... #else /* !(MIMSY == BOROGROVE) */ +... block 2 +... block 2 +... block 2 +... block 2 +... #endif /* MIMSY == BOROGROVE */ +... #endif /* defined(HAVE_OCELOT) */ +... ''' + +Here's how to use it: +>>> import sys +>>> if sys.version_info.major < 3: from cStringIO import StringIO +>>> if sys.version_info.major >= 3: from io import StringIO + +>>> OUTPUT = StringIO() +>>> translate(StringIO(INPUT), OUTPUT) +>>> assert OUTPUT.getvalue() == EXPECTED_OUTPUT + +Note that only #else and #endif lines are annotated. Existing comments +on those lines are removed. +""" + +import re + +# Any block with fewer than this many lines does not need annotations. +LINE_OBVIOUSNESS_LIMIT = 4 + +# Maximum line width. This includes a terminating newline character. +# +# (This is the maximum before encoding, so that if the the operating system +# uses multiple characers to encode newline, that's still okay.) +LINE_WIDTH=80 + +class Problem(Exception): + pass + +def close_parens_needed(expr): + """Return the number of left-parentheses needed to make 'expr' + balanced. + + >>> close_parens_needed("1+2") + 0 + >>> close_parens_needed("(1 + 2)") + 0 + >>> close_parens_needed("(1 + 2") + 1 + >>> close_parens_needed("(1 + (2 *") + 2 + >>> close_parens_needed("(1 + (2 * 3) + (4") + 2 + """ + return expr.count("(") - expr.count(")") + +def truncate_expression(expr, new_width): + """Given a parenthesized C expression in 'expr', try to return a new + expression that is similar to 'expr', but no more than 'new_width' + characters long. + + Try to return an expression with balanced parentheses. + + >>> truncate_expression("1+2+3", 8) + '1+2+3' + >>> truncate_expression("1+2+3+4+5", 8) + '1+2+3...' + >>> truncate_expression("(1+2+3+4)", 8) + '(1+2...)' + >>> truncate_expression("(1+(2+3+4))", 8) + '(1+...)' + >>> truncate_expression("(((((((((", 8) + '((...))' + """ + if len(expr) <= new_width: + # The expression is already short enough. + return expr + + ellipsis = "..." + + # Start this at the minimum that we might truncate. + n_to_remove = len(expr) + len(ellipsis) - new_width + + # Try removing characters, one by one, until we get something where + # re-balancing the parentheses still fits within the limit. + while n_to_remove < len(expr): + truncated = expr[:-n_to_remove] + ellipsis + truncated += ")" * close_parens_needed(truncated) + if len(truncated) <= new_width: + return truncated + n_to_remove += 1 + + return ellipsis + +def commented_line(fmt, argument, maxwidth=LINE_WIDTH): + # (This is a raw docstring so that our doctests can use \.) + r""" + Return fmt%argument, for use as a commented line. If the line would + be longer than maxwidth, truncate argument but try to keep its + parentheses balanced. + + Requires that fmt%"..." will fit into maxwidth characters. + + Requires that fmt ends with a newline. + + >>> commented_line("/* %s */\n", "hello world", 32) + '/* hello world */\n' + >>> commented_line("/* %s */\n", "hello world", 15) + '/* hello... */\n' + >>> commented_line("#endif /* %s */\n", "((1+2) && defined(FOO))", 32) + '#endif /* ((1+2) && defi...) */\n' + + + The default line limit is 80 characters including the newline: + + >>> long_argument = "long " * 100 + >>> long_line = commented_line("#endif /* %s */\n", long_argument) + >>> len(long_line) + 80 + + >>> long_line[:40] + '#endif /* long long long long long long ' + >>> long_line[40:] + 'long long long long long long lon... */\n' + + If a line works out to being 80 characters naturally, it isn't truncated, + and no ellipsis is added. + + >>> medium_argument = "a"*66 + >>> medium_line = commented_line("#endif /* %s */\n", medium_argument) + >>> len(medium_line) + 80 + >>> "..." in medium_line + False + >>> medium_line[:40] + '#endif /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + >>> medium_line[40:] + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */\n' + + + """ + assert fmt.endswith("\n") + result = fmt % argument + if len(result) <= maxwidth: + return result + else: + # How long can we let the argument be? Try filling in the + # format with an empty argument to find out. + max_arg_width = maxwidth - len(fmt % "") + result = fmt % truncate_expression(argument, max_arg_width) + assert len(result) <= maxwidth + return result + +def negate(expr): + """Return a negated version of expr; try to avoid double-negation. + + We usually wrap expressions in parentheses and add a "!". + >>> negate("A && B") + '!(A && B)' + + But if we recognize the expression as negated, we can restore it. + >>> negate(negate("A && B")) + 'A && B' + + The same applies for defined(FOO). + >>> negate("defined(FOO)") + '!defined(FOO)' + >>> negate(negate("defined(FOO)")) + 'defined(FOO)' + + Internal parentheses don't confuse us: + >>> negate("!(FOO) && !(BAR)") + '!(!(FOO) && !(BAR))' + + """ + expr = expr.strip() + # See whether we match !(...), with no intervening close-parens. + m = re.match(r'^!\s*\(([^\)]*)\)$', expr) + if m: + return m.group(1) + + + # See whether we match !?defined(...), with no intervening close-parens. + m = re.match(r'^(!?)\s*(defined\([^\)]*\))$', expr) + if m: + if m.group(1) == "!": + prefix = "" + else: + prefix = "!" + return prefix + m.group(2) + + return "!(%s)" % expr + +def uncomment(s): + """ + Remove existing trailing comments from an #else or #endif line. + """ + s = re.sub(r'//.*','',s) + s = re.sub(r'/\*.*','',s) + return s.strip() + +def translate(f_in, f_out): + """ + Read a file from f_in, and write its annotated version to f_out. + """ + # A stack listing our current if/else state. Each member of the stack + # is a list of directives. Each directive is a 3-tuple of + # (command, rest, lineno) + # where "command" is one of if/ifdef/ifndef/else/elif, and where + # "rest" is an expression in a format suitable for use with #if, and where + # lineno is the line number where the directive occurred. + stack = [] + # the stack element corresponding to the top level of the file. + whole_file = [] + 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: + # no directive, so we can just write it out. + 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"): + # We stay at the same level on the stack. If we have an #else, + # we comment it. + 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(commented_line("#else /* %s */\n", + negate(cur_level[0][1]))) + else: + f_out.write(line) + cur_level.append((command, rest, lineno)) + else: + # We pop one element on the stack, and comment an endif. + 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(commented_line("#endif /* %s */\n", + cur_level[0][1])) + else: + f_out.write(commented_line("#endif /* %s || ... */\n", + cur_level[0][1])) + cur_level = stack.pop() + if len(stack) or cur_level != whole_file: + raise Problem("Missing #endif") + +if __name__ == '__main__': + + import sys,os + + if sys.argv[1] == "--self-test": + import doctest + doctest.testmod() + sys.exit(0) + + 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/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt index 2e676d9045..e4d231d9e7 100644 --- a/scripts/maint/practracker/exceptions.txt +++ b/scripts/maint/practracker/exceptions.txt @@ -6,8 +6,12 @@ # # There are three kinds of problems that we recognize right now: # function-size -- a function of more than 100 lines. -# file-size -- a file of more than 3000 lines. -# include-count -- a file with more than 50 #includes. +# file-size -- a .c file of more than 3000 lines, or a .h +# file with more than 500 lines. +# include-count -- a .c file with more than 50 #includes, +# or a .h file with more than 15 #includes. +# dependency-violation -- a file includes a header that it should +# not, according to an advisory .may_include file. # # Each line below represents a single exception that practracker should # _ignore_. Each line has four parts: @@ -29,14 +33,14 @@ # # Remember: It is better to fix the problem than to add a new exception! -problem file-size /src/app/config/config.c 8518 +problem file-size /src/app/config/config.c 8459 problem include-count /src/app/config/config.c 89 problem function-size /src/app/config/config.c:options_act_reversible() 296 problem function-size /src/app/config/config.c:options_act() 589 problem function-size /src/app/config/config.c:resolve_my_address() 190 problem function-size /src/app/config/config.c:options_validate() 1209 problem function-size /src/app/config/config.c:options_init_from_torrc() 207 -problem function-size /src/app/config/config.c:options_init_from_string() 171 +problem function-size /src/app/config/config.c:options_init_from_string() 113 problem function-size /src/app/config/config.c:options_init_logs() 145 problem function-size /src/app/config/config.c:parse_bridge_line() 104 problem function-size /src/app/config/config.c:parse_transport_line() 189 @@ -44,7 +48,7 @@ problem function-size /src/app/config/config.c:parse_dir_authority_line() 150 problem function-size /src/app/config/config.c:parse_dir_fallback_line() 101 problem function-size /src/app/config/config.c:parse_port_config() 446 problem function-size /src/app/config/config.c:parse_ports() 168 -problem file-size /src/app/config/or_options_st.h 1112 +problem file-size /src/app/config/or_options_st.h 1121 problem include-count /src/app/main/main.c 68 problem function-size /src/app/main/main.c:dumpstats() 102 problem function-size /src/app/main/main.c:tor_init() 137 @@ -52,11 +56,12 @@ problem function-size /src/app/main/main.c:sandbox_init_filter() 291 problem function-size /src/app/main/main.c:run_tor_main_loop() 105 problem function-size /src/app/main/ntmain.c:nt_service_install() 126 problem dependency-violation /src/core/crypto/hs_ntor.c 1 +problem dependency-violation /src/core/crypto/hs_ntor.h 1 problem dependency-violation /src/core/crypto/onion_crypto.c 5 problem dependency-violation /src/core/crypto/onion_fast.c 1 problem dependency-violation /src/core/crypto/onion_tap.c 3 problem dependency-violation /src/core/crypto/relay_crypto.c 9 -problem file-size /src/core/mainloop/connection.c 5569 +problem file-size /src/core/mainloop/connection.c 5575 problem include-count /src/core/mainloop/connection.c 62 problem function-size /src/core/mainloop/connection.c:connection_free_minimal() 185 problem function-size /src/core/mainloop/connection.c:connection_listener_new() 324 @@ -79,9 +84,11 @@ problem dependency-violation /src/core/mainloop/mainloop_sys.c 1 problem dependency-violation /src/core/mainloop/netstatus.c 4 problem dependency-violation /src/core/mainloop/periodic.c 2 problem dependency-violation /src/core/or/address_set.c 1 +problem dependency-violation /src/core/or/cell_queue_st.h 1 problem file-size /src/core/or/channel.c 3487 problem dependency-violation /src/core/or/channel.c 9 problem file-size /src/core/or/channel.h 780 +problem dependency-violation /src/core/or/channel.h 1 problem dependency-violation /src/core/or/channelpadding.c 6 problem function-size /src/core/or/channeltls.c:channel_tls_handle_var_cell() 160 problem function-size /src/core/or/channeltls.c:channel_tls_process_versions_cell() 170 @@ -101,6 +108,7 @@ problem function-size /src/core/or/circuitlist.c:circuit_find_to_cannibalize() 1 problem function-size /src/core/or/circuitlist.c:circuit_about_to_free() 120 problem function-size /src/core/or/circuitlist.c:circuits_handle_oom() 117 problem dependency-violation /src/core/or/circuitlist.c 19 +problem dependency-violation /src/core/or/circuitlist.h 1 problem function-size /src/core/or/circuitmux.c:circuitmux_set_policy() 109 problem function-size /src/core/or/circuitmux.c:circuitmux_attach_circuit() 113 problem dependency-violation /src/core/or/circuitmux_ewma.c 2 @@ -113,22 +121,22 @@ problem function-size /src/core/or/circuitpadding_machines.c:circpad_machine_cli problem dependency-violation /src/core/or/circuitpadding_machines.c 1 problem function-size /src/core/or/circuitstats.c:circuit_build_times_parse_state() 123 problem dependency-violation /src/core/or/circuitstats.c 11 -problem file-size /src/core/or/circuituse.c 3162 +problem file-size /src/core/or/circuituse.c 3161 problem function-size /src/core/or/circuituse.c:circuit_is_acceptable() 128 problem function-size /src/core/or/circuituse.c:circuit_expire_building() 394 problem function-size /src/core/or/circuituse.c:circuit_log_ancient_one_hop_circuits() 126 problem function-size /src/core/or/circuituse.c:circuit_build_failed() 149 problem function-size /src/core/or/circuituse.c:circuit_launch_by_extend_info() 108 -problem function-size /src/core/or/circuituse.c:circuit_get_open_circ_or_launch() 352 +problem function-size /src/core/or/circuituse.c:circuit_get_open_circ_or_launch() 351 problem function-size /src/core/or/circuituse.c:connection_ap_handshake_attach_circuit() 244 problem dependency-violation /src/core/or/circuituse.c 23 problem function-size /src/core/or/command.c:command_process_create_cell() 156 problem function-size /src/core/or/command.c:command_process_relay_cell() 132 problem dependency-violation /src/core/or/command.c 8 -problem file-size /src/core/or/connection_edge.c 4596 +problem file-size /src/core/or/connection_edge.c 4601 problem include-count /src/core/or/connection_edge.c 65 problem function-size /src/core/or/connection_edge.c:connection_ap_expire_beginning() 117 -problem function-size /src/core/or/connection_edge.c:connection_ap_handshake_rewrite() 191 +problem function-size /src/core/or/connection_edge.c:connection_ap_handshake_rewrite() 193 problem function-size /src/core/or/connection_edge.c:connection_ap_handle_onion() 185 problem function-size /src/core/or/connection_edge.c:connection_ap_handshake_rewrite_and_attach() 421 problem function-size /src/core/or/connection_edge.c:connection_ap_handshake_send_begin() 111 @@ -136,6 +144,7 @@ problem function-size /src/core/or/connection_edge.c:connection_ap_handshake_soc problem function-size /src/core/or/connection_edge.c:connection_exit_begin_conn() 185 problem function-size /src/core/or/connection_edge.c:connection_exit_connect() 102 problem dependency-violation /src/core/or/connection_edge.c 27 +problem dependency-violation /src/core/or/connection_edge.h 1 problem file-size /src/core/or/connection_or.c 3122 problem include-count /src/core/or/connection_or.c 51 problem function-size /src/core/or/connection_or.c:connection_or_group_set_badness_() 105 @@ -146,6 +155,7 @@ problem dependency-violation /src/core/or/dos.c 5 problem dependency-violation /src/core/or/onion.c 2 problem file-size /src/core/or/or.h 1107 problem include-count /src/core/or/or.h 49 +problem dependency-violation /src/core/or/or.h 1 problem dependency-violation /src/core/or/or_periodic.c 1 problem file-size /src/core/or/policies.c 3249 problem function-size /src/core/or/policies.c:policy_summarize() 107 @@ -179,18 +189,18 @@ problem function-size /src/feature/client/addressmap.c:addressmap_rewrite() 109 problem function-size /src/feature/client/bridges.c:rewrite_node_address_for_bridge() 126 problem function-size /src/feature/client/circpathbias.c:pathbias_measure_close_rate() 108 problem function-size /src/feature/client/dnsserv.c:evdns_server_callback() 153 -problem file-size /src/feature/client/entrynodes.c 3824 +problem file-size /src/feature/client/entrynodes.c 3825 problem function-size /src/feature/client/entrynodes.c:entry_guards_upgrade_waiting_circuits() 155 problem function-size /src/feature/client/entrynodes.c:entry_guard_parse_from_state() 246 problem file-size /src/feature/client/entrynodes.h 639 problem function-size /src/feature/client/transports.c:handle_proxy_line() 108 problem function-size /src/feature/client/transports.c:parse_method_line_helper() 110 problem function-size /src/feature/client/transports.c:create_managed_proxy_environment() 109 -problem function-size /src/feature/control/control.c:connection_control_process_inbuf() 136 +problem function-size /src/feature/control/control.c:connection_control_process_inbuf() 113 problem function-size /src/feature/control/control_auth.c:handle_control_authenticate() 186 problem function-size /src/feature/control/control_cmd.c:handle_control_extendcircuit() 150 problem function-size /src/feature/control/control_cmd.c:handle_control_add_onion() 256 -problem function-size /src/feature/control/control_cmd.c:add_onion_helper_keyarg() 116 +problem function-size /src/feature/control/control_cmd.c:add_onion_helper_keyarg() 117 problem function-size /src/feature/control/control_events.c:control_event_stream_status() 118 problem include-count /src/feature/control/control_getinfo.c 54 problem function-size /src/feature/control/control_getinfo.c:getinfo_helper_misc() 108 @@ -227,7 +237,6 @@ problem function-size /src/feature/dirclient/dirclient.c:handle_response_fetch_c problem function-size /src/feature/dircommon/consdiff.c:gen_ed_diff() 203 problem function-size /src/feature/dircommon/consdiff.c:apply_ed_diff() 158 problem function-size /src/feature/dirparse/authcert_parse.c:authority_cert_parse_from_string() 181 -problem function-size /src/feature/dirparse/microdesc_parse.c:microdescs_parse_from_string() 166 problem function-size /src/feature/dirparse/ns_parse.c:routerstatus_parse_entry_from_string() 280 problem function-size /src/feature/dirparse/ns_parse.c:networkstatus_verify_bw_weights() 389 problem function-size /src/feature/dirparse/ns_parse.c:networkstatus_parse_vote_from_string() 635 @@ -244,11 +253,11 @@ problem function-size /src/feature/hs/hs_common.c:hs_get_responsible_hsdirs() 10 problem function-size /src/feature/hs/hs_config.c:config_service_v3() 107 problem function-size /src/feature/hs/hs_config.c:config_generic_service() 138 problem function-size /src/feature/hs/hs_descriptor.c:desc_encode_v3() 101 -problem function-size /src/feature/hs/hs_descriptor.c:decrypt_desc_layer() 105 +problem function-size /src/feature/hs/hs_descriptor.c:decrypt_desc_layer() 111 problem function-size /src/feature/hs/hs_descriptor.c:decode_introduction_point() 122 problem function-size /src/feature/hs/hs_descriptor.c:desc_decode_superencrypted_v3() 107 problem function-size /src/feature/hs/hs_descriptor.c:desc_decode_encrypted_v3() 107 -problem file-size /src/feature/hs/hs_service.c 4116 +problem file-size /src/feature/hs/hs_service.c 4182 problem function-size /src/feature/keymgt/loadkey.c:ed_key_init_from_file() 326 problem function-size /src/feature/nodelist/authcert.c:trusted_dirs_load_certs_from_string() 123 problem function-size /src/feature/nodelist/authcert.c:authority_certs_fetch_missing() 295 @@ -270,7 +279,7 @@ problem function-size /src/feature/nodelist/routerlist.c:update_extrainfo_downlo problem function-size /src/feature/relay/dns.c:dns_resolve_impl() 131 problem function-size /src/feature/relay/dns.c:configure_nameservers() 161 problem function-size /src/feature/relay/dns.c:evdns_callback() 108 -problem file-size /src/feature/relay/router.c 3522 +problem file-size /src/feature/relay/router.c 3524 problem include-count /src/feature/relay/router.c 56 problem function-size /src/feature/relay/router.c:init_keys() 252 problem function-size /src/feature/relay/router.c:get_my_declared_family() 114 @@ -280,14 +289,14 @@ problem function-size /src/feature/relay/routerkeys.c:load_ed_keys() 294 problem function-size /src/feature/rend/rendcache.c:rend_cache_store_v2_desc_as_client() 190 problem function-size /src/feature/rend/rendclient.c:rend_client_send_introduction() 219 problem function-size /src/feature/rend/rendcommon.c:rend_encode_v2_descriptors() 221 -problem function-size /src/feature/rend/rendmid.c:rend_mid_establish_intro_legacy() 104 +problem function-size /src/feature/rend/rendmid.c:rend_mid_establish_intro_legacy() 105 problem function-size /src/feature/rend/rendparse.c:rend_parse_v2_service_descriptor() 181 problem function-size /src/feature/rend/rendparse.c:rend_parse_introduction_points() 129 -problem file-size /src/feature/rend/rendservice.c 4511 +problem file-size /src/feature/rend/rendservice.c 4522 problem function-size /src/feature/rend/rendservice.c:rend_service_prune_list_impl_() 107 problem function-size /src/feature/rend/rendservice.c:rend_config_service() 162 problem function-size /src/feature/rend/rendservice.c:rend_service_load_auth_keys() 178 -problem function-size /src/feature/rend/rendservice.c:rend_service_receive_introduction() 330 +problem function-size /src/feature/rend/rendservice.c:rend_service_receive_introduction() 334 problem function-size /src/feature/rend/rendservice.c:rend_service_parse_intro_for_v3() 111 problem function-size /src/feature/rend/rendservice.c:rend_service_decrypt_intro() 112 problem function-size /src/feature/rend/rendservice.c:rend_service_intro_has_opened() 126 @@ -325,12 +334,3 @@ problem function-size /src/tools/tor-gencert.c:parse_commandline() 111 problem function-size /src/tools/tor-resolve.c:build_socks5_resolve_request() 102 problem function-size /src/tools/tor-resolve.c:do_resolve() 171 problem function-size /src/tools/tor-resolve.c:main() 112 - -problem dependency-violation /scripts/maint/practracker/testdata/a.c 3 -problem dependency-violation /scripts/maint/practracker/testdata/header.h 3 -problem dependency-violation /src/core/crypto/hs_ntor.h 1 -problem dependency-violation /src/core/or/cell_queue_st.h 1 -problem dependency-violation /src/core/or/channel.h 1 -problem dependency-violation /src/core/or/circuitlist.h 1 -problem dependency-violation /src/core/or/connection_edge.h 1 -problem dependency-violation /src/core/or/or.h 1 diff --git a/scripts/maint/practracker/practracker.py b/scripts/maint/practracker/practracker.py index ce9c5f5d82..5f26d28cea 100755 --- a/scripts/maint/practracker/practracker.py +++ b/scripts/maint/practracker/practracker.py @@ -147,7 +147,7 @@ HEADER="""\ # file-size -- a .c file of more than {MAX_FILE_SIZE} lines, or a .h # file with more than {MAX_H_FILE_SIZE} lines. # include-count -- a .c file with more than {MAX_INCLUDE_COUNT} #includes, - or a .h file with more than {MAX_H_INCLUDE_COUNT} #includes. +# or a .h file with more than {MAX_H_INCLUDE_COUNT} #includes. # dependency-violation -- a file includes a header that it should # not, according to an advisory .may_include file. # @@ -181,7 +181,7 @@ def main(argv): parser.add_argument("--regen", action="store_true", help="Regenerate the exceptions file") parser.add_argument("--list-overbroad", action="store_true", - help="List over-strict exceptions") + help="List over-broad exceptions") parser.add_argument("--exceptions", help="Override the location for the exceptions file") parser.add_argument("--strict", action="store_true", @@ -224,6 +224,11 @@ def main(argv): filt.addThreshold(problem.DependencyViolationItem("*.c", int(args.max_dependency_violations))) filt.addThreshold(problem.DependencyViolationItem("*.h", int(args.max_dependency_violations))) + if args.list_overbroad and args.regen: + print("Cannot use --regen with --list-overbroad", + file=sys.stderr) + sys.exit(1) + # 1) Get all the .c files we care about files_list = util.get_tor_c_files(TOR_TOPDIR, args.include_dir) @@ -239,6 +244,10 @@ def main(argv): ProblemVault = problem.ProblemVault(exceptions_file) problem_file = sys.stdout + if args.list_overbroad: + # If we're listing overbroad exceptions, don't list problems. + problem_file = util.NullFile() + # 2.1) Adjust the exceptions so that we warn only about small problems, # and produce errors on big ones. if not (args.regen or args.list_overbroad or args.strict): diff --git a/scripts/maint/practracker/problem.py b/scripts/maint/practracker/problem.py index 88e1044fb7..d21840a213 100644 --- a/scripts/maint/practracker/problem.py +++ b/scripts/maint/practracker/problem.py @@ -77,8 +77,10 @@ class ProblemVault(object): # (e.g. we went from 4k LoC to 3k LoC), but we do warn if the # situation worsened (e.g. we went from 60 includes to 80). status = problem.is_worse_than(self.exceptions[problem.key()]) - if status == STATUS_OK: - self.used_exception_for[problem.key()] = problem + + # Remember that we used this exception, so that we can later + # determine whether the exception was overbroad. + self.used_exception_for[problem.key()] = problem return status diff --git a/scripts/maint/practracker/test_practracker.sh b/scripts/maint/practracker/test_practracker.sh index bfbd0c6560..9b107e071d 100755 --- a/scripts/maint/practracker/test_practracker.sh +++ b/scripts/maint/practracker/test_practracker.sh @@ -61,3 +61,9 @@ echo "ex1:" run_practracker --exceptions "${DATA}/ex1.txt" > "${TMPDIR}/ex1-received.txt" compare "${TMPDIR}/ex1-received.txt" "${DATA}/ex1-expected.txt" + +echo "ex1.overbroad:" + +run_practracker --exceptions "${DATA}/ex1.txt" --list-overbroad > "${TMPDIR}/ex1-overbroad-received.txt" + +compare "${TMPDIR}/ex1-overbroad-received.txt" "${DATA}/ex1-overbroad-expected.txt" diff --git a/scripts/maint/practracker/testdata/ex1-overbroad-expected.txt b/scripts/maint/practracker/testdata/ex1-overbroad-expected.txt new file mode 100644 index 0000000000..f69c608f40 --- /dev/null +++ b/scripts/maint/practracker/testdata/ex1-overbroad-expected.txt @@ -0,0 +1,2 @@ +problem file-size a.c 40 -> 38 +problem file-size z.c 100 -> 0 diff --git a/scripts/maint/practracker/testdata/ex1.txt b/scripts/maint/practracker/testdata/ex1.txt index f619e33b22..c698005d07 100644 --- a/scripts/maint/practracker/testdata/ex1.txt +++ b/scripts/maint/practracker/testdata/ex1.txt @@ -1,5 +1,5 @@ -problem file-size a.c 38 +problem file-size a.c 40 problem include-count a.c 4 # this problem will produce an error problem function-size a.c:i_am_a_function() 8 @@ -8,6 +8,9 @@ problem function-size a.c:another_function() 11 problem file-size b.c 15 # This is removed, and so will produce an error. # problem function-size b.c:foo() 4 +# This exception isn't used. +problem file-size z.c 100 + problem function-size b.c:bar() 5 problem dependency-violation a.c 3 problem dependency-violation header.h 3 diff --git a/scripts/maint/practracker/util.py b/scripts/maint/practracker/util.py index 4b42565528..df629110c2 100644 --- a/scripts/maint/practracker/util.py +++ b/scripts/maint/practracker/util.py @@ -41,3 +41,10 @@ def get_tor_c_files(tor_topdir, include_dirs=None): files_list.append(full_path) return files_list + +class NullFile: + """A file-like object that we can us to suppress output.""" + def __init__(self): + pass + def write(self, s): + pass |