Commit c2f01120 authored by Tim Peters's avatar Tim Peters

vgetargskeywords()

+ Squash another potential buffer overrun.
+ Simplify the keyword-arg loop by decrementing the count of keywords
  remaining instead of incrementing Yet Another Variable; also break
  out early if the number of keyword args remaining hits 0.

Since I hit the function's closing curly brace with this patch, that's
enough of this for now <wink>.
parent b639d497
...@@ -1033,9 +1033,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, ...@@ -1033,9 +1033,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
int min, max; int min, max;
char *formatsave; char *formatsave;
int i, len, nargs, nkeywords; int i, len, nargs, nkeywords;
char *msg, *ks, **p; char *msg, **p;
int pos, match, converted;
PyObject *key, *value;
assert(args != NULL && PyTuple_Check(args)); assert(args != NULL && PyTuple_Check(args));
assert(keywords == NULL || PyDict_Check(keywords)); assert(keywords == NULL || PyDict_Check(keywords));
...@@ -1150,7 +1148,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, ...@@ -1150,7 +1148,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
PyErr_SetString(PyExc_TypeError, message); PyErr_SetString(PyExc_TypeError, message);
return 0; return 0;
} }
/* convert the positional arguments */
for (i = 0; i < nargs; i++) { for (i = 0; i < nargs; i++) {
if (*format == '|') if (*format == '|')
format++; format++;
...@@ -1162,13 +1161,12 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, ...@@ -1162,13 +1161,12 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
} }
} }
/* handle no keyword parameters in call */ /* handle no keyword parameters in call */
if (nkeywords == 0) if (nkeywords == 0)
return 1; return 1;
/* convert the keyword arguments; this uses the format /* convert the keyword arguments; this uses the format
string where it was left after processing args */ string where it was left after processing args */
converted = 0;
for (i = nargs; i < max; i++) { for (i = nargs; i < max; i++) {
PyObject *item; PyObject *item;
if (*format == '|') if (*format == '|')
...@@ -1182,7 +1180,9 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, ...@@ -1182,7 +1180,9 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
seterror(i+1, msg, levels, fname, message); seterror(i+1, msg, levels, fname, message);
return 0; return 0;
} }
converted++; --nkeywords;
if (nkeywords == 0)
break;
} }
else if (PyErr_Occurred()) else if (PyErr_Occurred())
return 0; return 0;
...@@ -1196,11 +1196,12 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, ...@@ -1196,11 +1196,12 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
} }
/* make sure there are no extraneous keyword arguments */ /* make sure there are no extraneous keyword arguments */
pos = 0; if (nkeywords > 0) {
if (converted < nkeywords) { PyObject *key, *value;
int pos = 0;
while (PyDict_Next(keywords, &pos, &key, &value)) { while (PyDict_Next(keywords, &pos, &key, &value)) {
match = 0; int match = 0;
ks = PyString_AsString(key); char *ks = PyString_AsString(key);
for (i = 0; i < max; i++) { for (i = 0; i < max; i++) {
if (!strcmp(ks, kwlist[i])) { if (!strcmp(ks, kwlist[i])) {
match = 1; match = 1;
...@@ -1208,15 +1209,15 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, ...@@ -1208,15 +1209,15 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format,
} }
} }
if (!match) { if (!match) {
sprintf(msgbuf, PyErr_Format(PyExc_TypeError,
"%s is an invalid keyword argument for this function", "'%s' is an invalid keyword "
ks); "argument for this function",
PyErr_SetString(PyExc_TypeError, msgbuf); ks);
return 0; return 0;
} }
} }
} }
return 1; return 1;
} }
......
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