summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/getargs.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/Python/getargs.c b/Python/getargs.c
index 38c9dde..8ec7110 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -1403,6 +1403,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
int levels[32];
const char *fname, *msg, *custom_msg, *keyword;
int min = INT_MAX;
+ int max = INT_MAX;
int i, len, nargs, nkeywords;
PyObject *current_arg;
freelist_t freelist = {0, NULL};
@@ -1452,8 +1453,39 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
for (i = 0; i < len; i++) {
keyword = kwlist[i];
if (*format == '|') {
+ if (min != INT_MAX) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Invalid format string (| specified twice)");
+ return cleanreturn(0, &freelist);
+ }
+
min = i;
format++;
+
+ if (max != INT_MAX) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Invalid format string ($ before |)");
+ return cleanreturn(0, &freelist);
+ }
+ }
+ if (*format == '$') {
+ if (max != INT_MAX) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Invalid format string ($ specified twice)");
+ return cleanreturn(0, &freelist);
+ }
+
+ max = i;
+ format++;
+
+ if (max < nargs) {
+ PyErr_Format(PyExc_TypeError,
+ "Function takes %s %d positional arguments"
+ " (%d given)",
+ (min != INT_MAX) ? "at most" : "exactly",
+ max, nargs);
+ return cleanreturn(0, &freelist);
+ }
}
if (IS_END_OF_FORMAT(*format)) {
PyErr_Format(PyExc_RuntimeError,
@@ -1514,7 +1546,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
}
}
- if (!IS_END_OF_FORMAT(*format) && *format != '|') {
+ if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
PyErr_Format(PyExc_RuntimeError,
"more argument specifiers than keyword list entries "
"(remaining format:'%s')", format);