Commit f8cd3e86 authored by Tim Peters's avatar Tim Peters

PyArg_ParseTupleAndKeywords: return false on internal error, not -1 (I

introduced this bug just a little while ago, when *adding* internal error
checks).

vgetargskeywords:  Rewrote the section that crawls over the format string.
+ Added block comment so it won't take the next person 15 minutes to
  reverse-engineer what it's doing.
+ Lined up the "else" clauses.
+ Rearranged the ifs in decreasing order of likelihood (for speed).
parent 45772cde
...@@ -997,6 +997,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg) ...@@ -997,6 +997,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg)
/* Support for keyword arguments donated by /* Support for keyword arguments donated by
Geoff Philbrick <philbric@delphi.hks.com> */ Geoff Philbrick <philbric@delphi.hks.com> */
/* Return false (0) for error, else true. */
int int
PyArg_ParseTupleAndKeywords(PyObject *args, PyArg_ParseTupleAndKeywords(PyObject *args,
PyObject *keywords, PyObject *keywords,
...@@ -1012,7 +1013,7 @@ PyArg_ParseTupleAndKeywords(PyObject *args, ...@@ -1012,7 +1013,7 @@ PyArg_ParseTupleAndKeywords(PyObject *args,
kwlist == NULL) kwlist == NULL)
{ {
PyErr_BadInternalCall(); PyErr_BadInternalCall();
return -1; return 0;
} }
va_start(va, kwlist); va_start(va, kwlist);
...@@ -1028,10 +1029,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, ...@@ -1028,10 +1029,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
{ {
char msgbuf[256]; char msgbuf[256];
int levels[32]; int levels[32];
char *fname = NULL; char *fname, *message;
char *message = NULL; int min, max;
int min = -1;
int max = 0;
char *formatsave = format; char *formatsave = format;
int i, len, tplen, kwlen; int i, len, tplen, kwlen;
char *msg, *ks, **p; char *msg, *ks, **p;
...@@ -1044,44 +1043,49 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, ...@@ -1044,44 +1043,49 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
assert(kwlist != NULL); assert(kwlist != NULL);
assert(p_va != NULL); assert(p_va != NULL);
/* nested tuples cannot be parsed when using keyword arguments */ /* Search the format:
message <- error msg, if any (else NULL).
for (;;) { name <- routine name, if any (else NULL).
int c = *format++; min <- # of required arguments, or -1 if all are required.
if (c == '(') { max <- most arguments (required + optional).
PyErr_SetString(PyExc_SystemError, Raise error if a tuple arg spec is found.
"tuple found in format when using keyword arguments"); */
return 0; fname = message = NULL;
} min = -1;
else if (c == '\0') max = 0;
break; while ((i = *format++) != '\0') {
else if (c == ':') { if (isalpha(i) && i != 'e')
max++;
else if (i == '|')
min = max;
else if (i == ':') {
fname = format; fname = format;
break; break;
} else if (c == ';') { }
else if (i == ';') {
message = format; message = format;
break; break;
} else if (c == 'e') }
; /* Pass */ else if (i == '(') {
else if (isalpha(c)) PyErr_SetString(PyExc_SystemError,
max++; "tuple found in format when using keyword arguments");
else if (c == '|') return 0;
min = max; }
} }
if (min < 0) {
if (min < 0) /* All arguments are required. */
min = max; min = max;
}
format = formatsave; format = formatsave;
if (!PyTuple_Check(args)) { if (!PyTuple_Check(args)) {
PyErr_SetString(PyExc_SystemError, PyErr_SetString(PyExc_SystemError,
"new style getargs format but argument is not a tuple"); "new style getargs format but argument is not a tuple");
return 0; return 0;
} }
tplen = PyTuple_GET_SIZE(args); tplen = PyTuple_GET_SIZE(args);
/* do a cursory check of the keywords just to see how many we got */ /* do a cursory check of the keywords just to see how many we got */
kwlen = 0; kwlen = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment