[Cocci] Extracting types passed to variadic (varargs) functions
David Malcolm
dmalcolm at redhat.com
Tue Nov 17 21:28:10 CET 2009
On Tue, 2009-11-17 at 21:21 +0100, Julia Lawall wrote:
> On Tue, 17 Nov 2009, David Malcolm wrote:
>
> > On Mon, 2009-11-16 at 23:14 +0100, Julia Lawall wrote:
> > > On Mon, 16 Nov 2009, David Malcolm wrote:
> > >
> > > > I'm new to Coccinelle/spatch and have been experimenting with using it
> > > > upon CPython code [1]
> > > >
> > > > I'm attempting to validate a mini-language used in format strings by a
> > > > variadic API call. My code examines the types of the
> > > > variables passed as varargs, and attempts to check that they are
> > > > pointers of the correct types, according to a set of rules [2].
> > > >
> > > > Unfortunately, I couldn't see a way to match a variable-length list of
> > > > expressions, capturing the type of each expression.
> > >
> > > If you really want to analyze all of the arguments at once, I don't see
> > > how to do it. But perhaps the following would be acceptable (not tested):
> > >
> > > @check_PyArg_ParseTuple@
> > > position pos;
> > > expression args;
> > > expresion fmt;
> > > type t; t e;
> > > expression list[n] E;
> > > @@
> > >
> > > PyArg_ParseTuple(args at pos, fmt, E, e, ...)
> > >
> > > @script:python@
> > > fmt << check_PyArg_ParseTuple.fmt;
> > > pos << check_PyArg_ParseTuple.pos;
> > > t << check_PyArg_ParseTuple.t;
> > > n << check_PyArg_ParseTuple.n;
> > > @@
> > >
> > > num_errors += validate_types(pos[0], fmt.expr, n, t)
> > >
> > > (I'm not sure that the .expr is needed on fmt; or in any case I don't know
> > > what it does).
> > >
> > > Now validate_types takes a position, a format string, the number of
> > > arguments between the format string and some argument, and that argument.
> > > The python code will be called on each argument individually.
> >
> > Thanks. I tried this, but appeared to only match the final argument at
> > each call site.
> >
> > However, I reworked it to have an "expression list" both before _and_
> > after, thus:
> >
> > @ check_PyArg_ParseTuple @
> > position pos;
> > expression args;
> > expression fmt;
> > expression list[len_E] E;
> > expression list[len_F] F;
> > type t;
> > t e;
> > @@
> >
> > PyArg_ParseTuple at pos(args, fmt, E, e, F)
> >
> > @script:python@
> > 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)
> >
> > ...and it's now successfully matching the rule for each argument, and
> > supplying the index and the total number of arguments together which
> > each type, which seems to be everything I needed.
> >
> > Many thanks!
>
> Great! Although I will have to look into why the ... solution didn't
> work. Thanks for reporting the problem.
Aha: it was a mistake at my end.
I misread your email; I was trying:
PyArg_ParseTuple(args at pos, fmt, E, e)
rather than your suggestion of:
PyArg_ParseTuple(args at pos, fmt, E, e, ...)
Sorry about any confusion.
More information about the Cocci
mailing list