summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2009-11-13 17:21:58 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2009-11-13 17:21:58 -0500
commitcdfd25bd47710289cb119f1fc5088870f3418134 (patch)
tree6c2554cbe5f5bbc199fc96f7409268f1c8251a11
downloadcheck-cpython-cdfd25bd47710289cb119f1fc5088870f3418134.tar.gz
check-cpython-cdfd25bd47710289cb119f1fc5088870f3418134.tar.xz
check-cpython-cdfd25bd47710289cb119f1fc5088870f3418134.zip
Initial commit
-rw-r--r--buggy.c18
-rw-r--r--pyarg-parsetuple.cocci69
2 files changed, 87 insertions, 0 deletions
diff --git a/buggy.c b/buggy.c
new file mode 100644
index 0000000..96d8ab3
--- /dev/null
+++ b/buggy.c
@@ -0,0 +1,18 @@
+/*
+ Errroneus argument parsing of socket.htons() on 64bit big endian
+ machines.
+
+ Fixed in svn r34931
+*/
+
+static PyObject *
+socket_htons(PyObject *self, PyObject *args)
+{
+ unsigned long x1, x2;
+
+ if (!PyArg_ParseTuple(args, "i:htons", &x1)) {
+ return NULL;
+ }
+ x2 = (int)htons((short)x1);
+ return PyInt_FromLong(x2);
+}
diff --git a/pyarg-parsetuple.cocci b/pyarg-parsetuple.cocci
new file mode 100644
index 0000000..2bc454b
--- /dev/null
+++ b/pyarg-parsetuple.cocci
@@ -0,0 +1,69 @@
+@ParseTuple@
+expression args;
+expression fmt;
+type t1;
+t1 p1;
+@@
+
+PyArg_ParseTuple(args, fmt, p1)
+
+@script:python@
+args << ParseTuple.args;
+fmt << ParseTuple.fmt;
+t1 << ParseTuple.t1;
+
+@@
+
+"""
+Analyze
+"""
+# FIXME: generalize thisto varargs
+
+
+def get_types(strfmt):
+ """
+ Generate a list of C type names from a format string
+ """
+ result = []
+ i = 0
+ while i < len(strfmt):
+ c = strfmt[i]
+ if c == 'i':
+ result.append('int *')
+ if c in [':', ';']:
+ break
+ i += 1
+ return result
+
+class CExtensionError(Exception):
+ # Base class for errors discovered by static analysis in C extension code
+ pass
+
+class WrongNumberOfVars(CExtensionError):
+ pass
+
+class NotEnoughVars(WrongNumberOfVars):
+ pass
+
+class TooManyVars(WrongNumberOfVars):
+ pass
+
+class MismatchingType(WrongNumberOfVars):
+ pass
+
+def validate_types(format_string, actual_types):
+ exp_types = get_types(format_string)
+ if len(actual_types) < len(exp_types):
+ raise NotEnoughVars(actual_types, exp_types)
+ if len(actual_types) > len(exp_types):
+ raise TooManyVars(actual_types, exp_types)
+ for exp, actual in zip(exp_types, actual_types):
+ if exp != actual:
+ raise MismatchingType(exp, actual)
+
+print "args: %s" % args
+print "fmt: %s" % fmt
+print "var1: %s" % t1
+print get_types(fmt.expr)
+
+validate_types(fmt.expr, [t1])