[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