From cdfd25bd47710289cb119f1fc5088870f3418134 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 13 Nov 2009 17:21:58 -0500 Subject: Initial commit --- buggy.c | 18 +++++++++++++ pyarg-parsetuple.cocci | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 buggy.c create mode 100644 pyarg-parsetuple.cocci 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]) -- cgit