summaryrefslogtreecommitdiffstats
path: root/pyarg-parsetuple.cocci
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2009-11-17 14:47:25 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2009-11-17 14:47:25 -0500
commit28a01c0fd593df0f64d06b4205c5a93b8068ea51 (patch)
tree36eddd2ca00184c26d86af817f5ab6adceba69f5 /pyarg-parsetuple.cocci
parent254f88a995334acfe04b5774a6be048a365cdb86 (diff)
downloadcheck-cpython-28a01c0fd593df0f64d06b4205c5a93b8068ea51.tar.gz
check-cpython-28a01c0fd593df0f64d06b4205c5a93b8068ea51.tar.xz
check-cpython-28a01c0fd593df0f64d06b4205c5a93b8068ea51.zip
Generalize variadic function handling
Avoid having to manually write a rule for each number of variable arguments to PyArg_ParseTuple etc by capturing each argument in turn (with lists of prior and subsequent expressions). The downside is that the rule is invoked once per argument at each callsite, with knowledge of only one type, rather than invoking it once per callsite with knowledge of all arguments. Thanks to Julia Lawall and Nicolas Palix
Diffstat (limited to 'pyarg-parsetuple.cocci')
-rw-r--r--pyarg-parsetuple.cocci130
1 files changed, 52 insertions, 78 deletions
diff --git a/pyarg-parsetuple.cocci b/pyarg-parsetuple.cocci
index c0d9595..dd31702 100644
--- a/pyarg-parsetuple.cocci
+++ b/pyarg-parsetuple.cocci
@@ -16,123 +16,97 @@
@initialize:python@
"""
Analyze format strings passed to variadic function, compare to vararg types actually passed
-
-FIXME: generalize this to arbitrary number of varargs; how to express this in SmPL?
"""
import sys
sys.path.append('.')
-from validate import validate_types
+from validate import validate_type
num_errors = 0
-@ check_PyArg_ParseTuple_1 @
+@ check_PyArg_ParseTuple @
position pos;
expression args;
expression fmt;
-type t1;
-t1 e1;
+expression list[len_E] E;
+expression list[len_F] F;
+type t;
+t e;
@@
-PyArg_ParseTuple@pos(args, fmt, e1)
+PyArg_ParseTuple@pos(args, fmt, E, e, F)
@script:python@
-pos << check_PyArg_ParseTuple_1.pos;
-fmt << check_PyArg_ParseTuple_1.fmt;
-t1 << check_PyArg_ParseTuple_1.t1;
+pos << check_PyArg_ParseTuple.pos;
+fmt << check_PyArg_ParseTuple.fmt;
+len_E << check_PyArg_ParseTuple.len_E;
+len_F << check_PyArg_ParseTuple.len_F;
+t << check_PyArg_ParseTuple.t;
@@
+num_errors += validate_type(pos[0],
+ fmt.expr,
+ int(len_E),
+ int(len_E) + 1 + int(len_F),
+ t)
-# For some reason, locations are coming as a 1-tuple containing a Location (from
-# coccilibs.elems), rather than the location itself
-# Hence we use p1[0], not p1
-num_errors += validate_types(pos[0], fmt.expr, [t1])
+# likewise for PyArg_Parse etc:
-@ check_PyArg_ParseTuple_2 @
+@ check_PyArg_Parse @
position pos;
expression args;
expression fmt;
-type t1;
-t1 e1;
-type t2;
-t2 e2;
+expression list[len_E] E;
+expression list[len_F] F;
+type t;
+t e;
@@
-PyArg_ParseTuple(args@pos, fmt, e1, e2)
+PyArg_Parse@pos(args, fmt, E, e, F)
@script:python@
-fmt << check_PyArg_ParseTuple_2.fmt;
-pos << check_PyArg_ParseTuple_2.pos;
-t1 << check_PyArg_ParseTuple_2.t1;
-t2 << check_PyArg_ParseTuple_2.t2;
+pos << check_PyArg_Parse.pos;
+fmt << check_PyArg_Parse.fmt;
+len_E << check_PyArg_Parse.len_E;
+len_F << check_PyArg_Parse.len_F;
+t << check_PyArg_Parse.t;
@@
-num_errors += validate_types(pos[0], fmt.expr, [t1, t2])
+num_errors += validate_type(pos[0],
+ fmt.expr,
+ int(len_E),
+ int(len_E) + 1 + int(len_F),
+ t)
-@ check_PyArg_ParseTuple_3 @
+@ check_PyArg_ParseTupleAndKeywords @
position pos;
expression args;
+expression keywords;
expression fmt;
-type t1; t1 e1;
-type t2; t2 e2;
-type t3; t3 e3;
-@@
-
-PyArg_ParseTuple(args@pos, fmt, e1, e2, e3)
-
-@script:python@
-pos << check_PyArg_ParseTuple_3.pos;
-fmt << check_PyArg_ParseTuple_3.fmt;
-pos << check_PyArg_ParseTuple_3.pos;
-t1 << check_PyArg_ParseTuple_3.t1;
-t2 << check_PyArg_ParseTuple_3.t2;
-t3 << check_PyArg_ParseTuple_3.t3;
+expression argnames;
+expression list[len_E] E;
+expression list[len_F] F;
+type t;
+t e;
@@
-num_errors += validate_types(pos[0], fmt.expr, [t1, t2, t3])
-
-# and so on... need to find a general way of doing this, rather than repeating for 4, 5, 6...
-# likewise for PyArg_Parse:
+PyArg_ParseTupleAndKeywords@pos(args, keywords, fmt, argnames, E, e, F)
-@ check_PyArg_Parse_1 @
-position pos;
-expression args;
-expression fmt;
-type t1;
-t1 e1;
-@@
-
-PyArg_Parse@pos(args, fmt, e1)
@script:python@
-pos << check_PyArg_Parse_1.pos;
-args << check_PyArg_Parse_1.args;
-fmt << check_PyArg_Parse_1.fmt;
-pos << check_PyArg_Parse_1.pos;
-t1 << check_PyArg_Parse_1.t1;
+pos << check_PyArg_ParseTupleAndKeywords.pos;
+fmt << check_PyArg_ParseTupleAndKeywords.fmt;
+len_E << check_PyArg_ParseTupleAndKeywords.len_E;
+len_F << check_PyArg_ParseTupleAndKeywords.len_F;
+t << check_PyArg_ParseTupleAndKeywords.t;
@@
-num_errors += validate_types(pos[0], fmt.expr, [t1])
-
-# again, for all N
-# similarly for PyArg_ParseTupleAndKeywords:
+num_errors += validate_type(pos[0],
+ fmt.expr,
+ int(len_E),
+ int(len_E) + 1 + int(len_F),
+ t)
-@ check_PyArg_ParseTupleAndKeywords_1 @
-position pos;
-expression args, kw, fmt, keywords;
-type t1;
-t1 e1;
-@@
-PyArg_ParseTupleAndKeywords@pos(args, kw, fmt, keywords, e1)
-@script:python@
-pos << check_PyArg_Parse_1.pos;
-args << check_PyArg_Parse_1.args;
-fmt << check_PyArg_Parse_1.fmt;
-pos << check_PyArg_Parse_1.pos;
-t1 << check_PyArg_Parse_1.t1;
-@@
-num_errors += validate_types(pos[0], fmt.expr, [t1])
-# etc
@script:python @
@@