Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f8cd3e8

Browse files
committed
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).
1 parent 45772cd commit f8cd3e8

1 file changed

Lines changed: 34 additions & 30 deletions

File tree

Python/getargs.c

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg)
997997
/* Support for keyword arguments donated by
998998
Geoff Philbrick <[email protected]> */
999999

1000+
/* Return false (0) for error, else true. */
10001001
int
10011002
PyArg_ParseTupleAndKeywords(PyObject *args,
10021003
PyObject *keywords,
@@ -1012,7 +1013,7 @@ PyArg_ParseTupleAndKeywords(PyObject *args,
10121013
kwlist == NULL)
10131014
{
10141015
PyErr_BadInternalCall();
1015-
return -1;
1016+
return 0;
10161017
}
10171018

10181019
va_start(va, kwlist);
@@ -1028,10 +1029,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
10281029
{
10291030
char msgbuf[256];
10301031
int levels[32];
1031-
char *fname = NULL;
1032-
char *message = NULL;
1033-
int min = -1;
1034-
int max = 0;
1032+
char *fname, *message;
1033+
int min, max;
10351034
char *formatsave = format;
10361035
int i, len, tplen, kwlen;
10371036
char *msg, *ks, **p;
@@ -1044,44 +1043,49 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
10441043
assert(kwlist != NULL);
10451044
assert(p_va != NULL);
10461045

1047-
/* nested tuples cannot be parsed when using keyword arguments */
1048-
1049-
for (;;) {
1050-
int c = *format++;
1051-
if (c == '(') {
1052-
PyErr_SetString(PyExc_SystemError,
1053-
"tuple found in format when using keyword arguments");
1054-
return 0;
1055-
}
1056-
else if (c == '\0')
1057-
break;
1058-
else if (c == ':') {
1046+
/* Search the format:
1047+
message <- error msg, if any (else NULL).
1048+
name <- routine name, if any (else NULL).
1049+
min <- # of required arguments, or -1 if all are required.
1050+
max <- most arguments (required + optional).
1051+
Raise error if a tuple arg spec is found.
1052+
*/
1053+
fname = message = NULL;
1054+
min = -1;
1055+
max = 0;
1056+
while ((i = *format++) != '\0') {
1057+
if (isalpha(i) && i != 'e')
1058+
max++;
1059+
else if (i == '|')
1060+
min = max;
1061+
else if (i == ':') {
10591062
fname = format;
10601063
break;
1061-
} else if (c == ';') {
1064+
}
1065+
else if (i == ';') {
10621066
message = format;
10631067
break;
1064-
} else if (c == 'e')
1065-
; /* Pass */
1066-
else if (isalpha(c))
1067-
max++;
1068-
else if (c == '|')
1069-
min = max;
1068+
}
1069+
else if (i == '(') {
1070+
PyErr_SetString(PyExc_SystemError,
1071+
"tuple found in format when using keyword arguments");
1072+
return 0;
1073+
}
10701074
}
1071-
1072-
if (min < 0)
1075+
if (min < 0) {
1076+
/* All arguments are required. */
10731077
min = max;
1074-
1078+
}
10751079
format = formatsave;
1076-
1080+
10771081
if (!PyTuple_Check(args)) {
10781082
PyErr_SetString(PyExc_SystemError,
10791083
"new style getargs format but argument is not a tuple");
10801084
return 0;
10811085
}
1082-
1086+
10831087
tplen = PyTuple_GET_SIZE(args);
1084-
1088+
10851089
/* do a cursory check of the keywords just to see how many we got */
10861090

10871091
kwlen = 0;

0 commit comments

Comments
 (0)