mirror of
https://github.com/python/cpython.git
synced 2025-11-01 02:38:53 +00:00
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).
This commit is contained in:
parent
45772cde7e
commit
f8cd3e8621
1 changed files with 34 additions and 30 deletions
|
|
@ -997,6 +997,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg)
|
|||
/* Support for keyword arguments donated by
|
||||
Geoff Philbrick <philbric@delphi.hks.com> */
|
||||
|
||||
/* Return false (0) for error, else true. */
|
||||
int
|
||||
PyArg_ParseTupleAndKeywords(PyObject *args,
|
||||
PyObject *keywords,
|
||||
|
|
@ -1012,7 +1013,7 @@ PyArg_ParseTupleAndKeywords(PyObject *args,
|
|||
kwlist == NULL)
|
||||
{
|
||||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_start(va, kwlist);
|
||||
|
|
@ -1028,10 +1029,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
|
|||
{
|
||||
char msgbuf[256];
|
||||
int levels[32];
|
||||
char *fname = NULL;
|
||||
char *message = NULL;
|
||||
int min = -1;
|
||||
int max = 0;
|
||||
char *fname, *message;
|
||||
int min, max;
|
||||
char *formatsave = format;
|
||||
int i, len, tplen, kwlen;
|
||||
char *msg, *ks, **p;
|
||||
|
|
@ -1044,44 +1043,49 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
|
|||
assert(kwlist != NULL);
|
||||
assert(p_va != NULL);
|
||||
|
||||
/* nested tuples cannot be parsed when using keyword arguments */
|
||||
|
||||
for (;;) {
|
||||
int c = *format++;
|
||||
if (c == '(') {
|
||||
/* Search the format:
|
||||
message <- error msg, if any (else NULL).
|
||||
name <- routine name, if any (else NULL).
|
||||
min <- # of required arguments, or -1 if all are required.
|
||||
max <- most arguments (required + optional).
|
||||
Raise error if a tuple arg spec is found.
|
||||
*/
|
||||
fname = message = NULL;
|
||||
min = -1;
|
||||
max = 0;
|
||||
while ((i = *format++) != '\0') {
|
||||
if (isalpha(i) && i != 'e')
|
||||
max++;
|
||||
else if (i == '|')
|
||||
min = max;
|
||||
else if (i == ':') {
|
||||
fname = format;
|
||||
break;
|
||||
}
|
||||
else if (i == ';') {
|
||||
message = format;
|
||||
break;
|
||||
}
|
||||
else if (i == '(') {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"tuple found in format when using keyword arguments");
|
||||
return 0;
|
||||
}
|
||||
else if (c == '\0')
|
||||
break;
|
||||
else if (c == ':') {
|
||||
fname = format;
|
||||
break;
|
||||
} else if (c == ';') {
|
||||
message = format;
|
||||
break;
|
||||
} else if (c == 'e')
|
||||
; /* Pass */
|
||||
else if (isalpha(c))
|
||||
max++;
|
||||
else if (c == '|')
|
||||
min = max;
|
||||
}
|
||||
|
||||
if (min < 0)
|
||||
if (min < 0) {
|
||||
/* All arguments are required. */
|
||||
min = max;
|
||||
|
||||
}
|
||||
format = formatsave;
|
||||
|
||||
|
||||
if (!PyTuple_Check(args)) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"new style getargs format but argument is not a tuple");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
tplen = PyTuple_GET_SIZE(args);
|
||||
|
||||
|
||||
/* do a cursory check of the keywords just to see how many we got */
|
||||
|
||||
kwlen = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue