[tor-commits] [tor/master] Coccinelle scripts for control.c refactor

dgoulet at torproject.org dgoulet at torproject.org
Fri May 3 14:57:34 UTC 2019


commit 58ec88e8060508a253bbe8ba5c19b020a2629ea0
Author: Taylor Yu <catalyst at torproject.org>
Date:   Wed Apr 10 12:27:50 2019 -0500

    Coccinelle scripts for control.c refactor
---
 scripts/coccinelle/ctrl-reply-cleanup.cocci | 43 ++++++++++++++
 scripts/coccinelle/ctrl-reply.cocci         | 87 +++++++++++++++++++++++++++++
 scripts/coccinelle/tor-coccinelle.h         |  3 +
 3 files changed, 133 insertions(+)

diff --git a/scripts/coccinelle/ctrl-reply-cleanup.cocci b/scripts/coccinelle/ctrl-reply-cleanup.cocci
new file mode 100644
index 000000000..f085cd468
--- /dev/null
+++ b/scripts/coccinelle/ctrl-reply-cleanup.cocci
@@ -0,0 +1,43 @@
+// Script to clean up after ctrl-reply.cocci -- run as a separate step
+// because cleanup_write2 (even when disabled) somehow prevents the
+// match rule in ctrl-reply.cocci from matching.
+
+// If it doesn't have to be a printf, turn it into a write
+
+@ cleanup_write @
+expression E;
+constant code, s;
+@@
+-control_printf_endreply(E, code, s)
++control_write_endreply(E, code, s)
+
+// Use send_control_done() instead of explicitly writing it out
+@ cleanup_send_done @
+type T;
+identifier f != send_control_done;
+expression E;
+@@
+ T f(...) {
+<...
+-control_write_endreply(E, 250, "OK")
++send_control_done(E)
+ ...>
+ }
+
+// Clean up more printfs that could be writes
+//
+// For some reason, including this rule, even disabled, causes the
+// match rule in ctrl-reply.cocci to fail to match some code that has
+// %s in its format strings
+
+@ cleanup_write2 @
+expression E1, E2;
+constant code;
+@@
+(
+-control_printf_endreply(E1, code, "%s", E2)
++control_write_endreply(E1, code, E2)
+|
+-control_printf_midreply(E1, code, "%s", E2)
++control_write_midreply(E1, code, E2)
+)
diff --git a/scripts/coccinelle/ctrl-reply.cocci b/scripts/coccinelle/ctrl-reply.cocci
new file mode 100644
index 000000000..d6e9aeedd
--- /dev/null
+++ b/scripts/coccinelle/ctrl-reply.cocci
@@ -0,0 +1,87 @@
+// Script to edit control_*.c for refactored control reply output functions
+
+@ initialize:python @
+@@
+import re
+from coccilib.report import *
+
+# reply strings "NNN-foo", "NNN+foo", "NNN foo", etc.
+r = re.compile(r'^"(\d+)([ +-])(.*)\\r\\n"$')
+
+# Generate name of function to call based on which separator character
+# comes between the numeric code and the text
+def idname(sep, base):
+    if sep == '+':
+        return base + "datareply"
+    elif sep == '-':
+        return base + "midreply"
+    else:
+        return base + "endreply"
+
+# Generate the actual replacements used by the rules
+def gen(s, base, p):
+    pos = p[0]
+    print_report(pos, "%s %s" % (base, s))
+    m = r.match(s)
+    if m is None:
+        # String not correct format, so fail match
+        cocci.include_match(False)
+        print_report(pos, "BAD STRING %s" % s)
+        return
+
+    code, sep, s1 = m.groups()
+
+    if r'\r\n' in s1:
+        # Extra CRLF in string, so fail match
+        cocci.include_match(False)
+        print_report(pos, "extra CRLF in string %s" % s)
+        return
+
+    coccinelle.code = code
+    # Need a string that is a single C token, because Coccinelle only allows
+    # "identifiers" to be output from Python scripts?
+    coccinelle.body = '"%s"' % s1
+    coccinelle.id = idname(sep, base)
+    return
+
+@ match @
+identifier f;
+position p;
+expression E;
+constant s;
+@@
+(
+ connection_printf_to_buf at f@p(E, s, ...)
+|
+ connection_write_str_to_buf at f@p(s, E)
+)
+
+@ script:python sc1 @
+s << match.s;
+p << match.p;
+f << match.f;
+id;
+body;
+code;
+@@
+if f == 'connection_printf_to_buf':
+    gen(s, 'control_printf_', p)
+elif f == 'connection_write_str_to_buf':
+    gen(s, 'control_write_', p)
+else:
+    raise(ValueError("%s: %s" % (f, s)))
+
+@ replace @
+constant match.s;
+expression match.E;
+identifier match.f;
+identifier sc1.body, sc1.id, sc1.code;
+@@
+(
+-connection_write_str_to_buf at f(s, E)
++id(E, code, body)
+|
+-connection_printf_to_buf at f(E, s
++id(E, code, body
+ , ...)
+)
diff --git a/scripts/coccinelle/tor-coccinelle.h b/scripts/coccinelle/tor-coccinelle.h
new file mode 100644
index 000000000..8f625dcee
--- /dev/null
+++ b/scripts/coccinelle/tor-coccinelle.h
@@ -0,0 +1,3 @@
+#define MOCK_IMPL(a, b, c) a b c
+#define CHECK_PRINTF(a, b)
+#define STATIC static





More information about the tor-commits mailing list