]> granicus.if.org Git - python/commitdiff
Another veeeeeery old patch...
authorGuido van Rossum <guido@python.org>
Fri, 15 May 1998 22:04:07 +0000 (22:04 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 15 May 1998 22:04:07 +0000 (22:04 +0000)
Date:    Thu, 14 Sep 1995 12:18:20 -0400
From:    Alan Morse <alan@dvcorp.com>
To:      python-list@cwi.nl
Subject: getargs bug in 1.2 and 1.3 BETA

We have found a bug in the part of the getargs code that we added
and submitted, and which was incorporated into 1.1.

The parsing of "O?" format specifiers is not handled correctly;
there is no "else" for the "if" and therefore it can never fail.
What's worse, the advancing of the varargs pointer is not
handled properly, so from then on it is out of sync, wreaking
all sorts of havoc. (If it had failed properly, then the out-of-sync
varargs would not have been an issue.)

Below is the context diff for the change.

Note that I have made a few stylistic changes beyond adding the
else case, namely:

1) Making the "O" case follow the convention established by the other
format specifiers of getting all their vararg arguments before
performing the test, rather than getting some before and some after
the test passes.

2) Making the logic of the tests parallel, so the "if" part indicates
that the format is accepted and the "else" part indicates that the
format has failed. They were inconsistent with each other and with the
the other format specifiers.

-Alan Morse (amorse@dvcorp.com)

Python/getargs.c

index 502944dacf69ab68e8953c5e502d63e7881bbdd1..e4c2634796d10d80ae5628f783cba1c5dd1395e9 100644 (file)
@@ -640,22 +640,24 @@ convertsimple1(arg, p_format, p_va)
                        PyTypeObject *type;
                        PyObject **p;
                        if (*format == '!') {
-                               format++;
                                type = va_arg(*p_va, PyTypeObject*);
-                               if (arg->ob_type != type)
-                                       return type->tp_name;
-                               else {
-                                       p = va_arg(*p_va, PyObject **);
+                               p = va_arg(*p_va, PyObject **);
+                               format++;
+                               if (arg->ob_type == type)
                                        *p = arg;
-                               }
+                               else
+                                       return type->tp_name;
+
                        }
                        else if (*format == '?') {
                                inquiry pred = va_arg(*p_va, inquiry);
+                               p = va_arg(*p_va, PyObject **);
                                format++;
-                               if ((*pred)(arg)) {
-                                       p = va_arg(*p_va, PyObject **);
+                               if ((*pred)(arg)) 
                                        *p = arg;
-                               }
+                               else
+                                        return "(unspecified)";
+                               
                        }
                        else if (*format == '&') {
                                typedef int (*converter)