Branch data Line data Source code
1 : :
2 : : /* New getargs implementation */
3 : :
4 : : #include "Python.h"
5 : : #include "pycore_tuple.h" // _PyTuple_ITEMS()
6 : : #include "pycore_pylifecycle.h" // _PyArg_Fini
7 : :
8 : : #include <ctype.h>
9 : : #include <float.h>
10 : :
11 : :
12 : : #ifdef __cplusplus
13 : : extern "C" {
14 : : #endif
15 : : int PyArg_Parse(PyObject *, const char *, ...);
16 : : int PyArg_ParseTuple(PyObject *, const char *, ...);
17 : : int PyArg_VaParse(PyObject *, const char *, va_list);
18 : :
19 : : int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
20 : : const char *, char **, ...);
21 : : int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
22 : : const char *, char **, va_list);
23 : :
24 : : int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
25 : : struct _PyArg_Parser *, ...);
26 : : int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *,
27 : : struct _PyArg_Parser *, va_list);
28 : :
29 : : #ifdef HAVE_DECLSPEC_DLL
30 : : /* Export functions */
31 : : PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...);
32 : : PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs,
33 : : const char *format, ...);
34 : : PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs,
35 : : PyObject *kwnames,
36 : : struct _PyArg_Parser *parser, ...);
37 : : PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
38 : : PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
39 : : const char *, char **, ...);
40 : : PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
41 : : PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
42 : : PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
43 : : const char *, char **, va_list);
44 : :
45 : : PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
46 : : struct _PyArg_Parser *, ...);
47 : : PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
48 : : struct _PyArg_Parser *, va_list);
49 : : #endif
50 : :
51 : : #define FLAG_COMPAT 1
52 : : #define FLAG_SIZE_T 2
53 : :
54 : : typedef int (*destr_t)(PyObject *, void *);
55 : :
56 : :
57 : : /* Keep track of "objects" that have been allocated or initialized and
58 : : which will need to be deallocated or cleaned up somehow if overall
59 : : parsing fails.
60 : : */
61 : : typedef struct {
62 : : void *item;
63 : : destr_t destructor;
64 : : } freelistentry_t;
65 : :
66 : : typedef struct {
67 : : freelistentry_t *entries;
68 : : int first_available;
69 : : int entries_malloced;
70 : : } freelist_t;
71 : :
72 : : #define STATIC_FREELIST_ENTRIES 8
73 : :
74 : : /* Forward */
75 : : static int vgetargs1_impl(PyObject *args, PyObject *const *stack, Py_ssize_t nargs,
76 : : const char *format, va_list *p_va, int flags);
77 : : static int vgetargs1(PyObject *, const char *, va_list *, int);
78 : : static void seterror(Py_ssize_t, const char *, int *, const char *, const char *);
79 : : static const char *convertitem(PyObject *, const char **, va_list *, int, int *,
80 : : char *, size_t, freelist_t *);
81 : : static const char *converttuple(PyObject *, const char **, va_list *, int,
82 : : int *, char *, size_t, int, freelist_t *);
83 : : static const char *convertsimple(PyObject *, const char **, va_list *, int,
84 : : char *, size_t, freelist_t *);
85 : : static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **);
86 : : static int getbuffer(PyObject *, Py_buffer *, const char**);
87 : :
88 : : static int vgetargskeywords(PyObject *, PyObject *,
89 : : const char *, char **, va_list *, int);
90 : : static int vgetargskeywordsfast(PyObject *, PyObject *,
91 : : struct _PyArg_Parser *, va_list *, int);
92 : : static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
93 : : PyObject *keywords, PyObject *kwnames,
94 : : struct _PyArg_Parser *parser,
95 : : va_list *p_va, int flags);
96 : : static const char *skipitem(const char **, va_list *, int);
97 : :
98 : : int
99 : 0 : PyArg_Parse(PyObject *args, const char *format, ...)
100 : : {
101 : : int retval;
102 : : va_list va;
103 : :
104 : 0 : va_start(va, format);
105 : 0 : retval = vgetargs1(args, format, &va, FLAG_COMPAT);
106 : 0 : va_end(va);
107 : 0 : return retval;
108 : : }
109 : :
110 : : PyAPI_FUNC(int)
111 : 0 : _PyArg_Parse_SizeT(PyObject *args, const char *format, ...)
112 : : {
113 : : int retval;
114 : : va_list va;
115 : :
116 : 0 : va_start(va, format);
117 : 0 : retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
118 : 0 : va_end(va);
119 : 0 : return retval;
120 : : }
121 : :
122 : :
123 : : int
124 : 106645 : PyArg_ParseTuple(PyObject *args, const char *format, ...)
125 : : {
126 : : int retval;
127 : : va_list va;
128 : :
129 : 106645 : va_start(va, format);
130 : 106645 : retval = vgetargs1(args, format, &va, 0);
131 : 106645 : va_end(va);
132 : 106645 : return retval;
133 : : }
134 : :
135 : : PyAPI_FUNC(int)
136 : 23529 : _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
137 : : {
138 : : int retval;
139 : : va_list va;
140 : :
141 : 23529 : va_start(va, format);
142 : 23529 : retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
143 : 23529 : va_end(va);
144 : 23529 : return retval;
145 : : }
146 : :
147 : :
148 : : int
149 : 0 : _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
150 : : {
151 : : int retval;
152 : : va_list va;
153 : :
154 : 0 : va_start(va, format);
155 : 0 : retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0);
156 : 0 : va_end(va);
157 : 0 : return retval;
158 : : }
159 : :
160 : : PyAPI_FUNC(int)
161 : 1 : _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
162 : : {
163 : : int retval;
164 : : va_list va;
165 : :
166 : 1 : va_start(va, format);
167 : 1 : retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T);
168 : 1 : va_end(va);
169 : 1 : return retval;
170 : : }
171 : :
172 : :
173 : : int
174 : 0 : PyArg_VaParse(PyObject *args, const char *format, va_list va)
175 : : {
176 : : va_list lva;
177 : : int retval;
178 : :
179 : 0 : va_copy(lva, va);
180 : :
181 : 0 : retval = vgetargs1(args, format, &lva, 0);
182 : 0 : va_end(lva);
183 : 0 : return retval;
184 : : }
185 : :
186 : : PyAPI_FUNC(int)
187 : 0 : _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
188 : : {
189 : : va_list lva;
190 : : int retval;
191 : :
192 : 0 : va_copy(lva, va);
193 : :
194 : 0 : retval = vgetargs1(args, format, &lva, FLAG_SIZE_T);
195 : 0 : va_end(lva);
196 : 0 : return retval;
197 : : }
198 : :
199 : :
200 : : /* Handle cleanup of allocated memory in case of exception */
201 : :
202 : : static int
203 : 0 : cleanup_ptr(PyObject *self, void *ptr)
204 : : {
205 : 0 : void **pptr = (void **)ptr;
206 : 0 : PyMem_Free(*pptr);
207 : 0 : *pptr = NULL;
208 : 0 : return 0;
209 : : }
210 : :
211 : : static int
212 : 0 : cleanup_buffer(PyObject *self, void *ptr)
213 : : {
214 : 0 : Py_buffer *buf = (Py_buffer *)ptr;
215 [ # # ]: 0 : if (buf) {
216 : 0 : PyBuffer_Release(buf);
217 : : }
218 : 0 : return 0;
219 : : }
220 : :
221 : : static int
222 : 0 : addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
223 : : {
224 : : int index;
225 : :
226 : 0 : index = freelist->first_available;
227 : 0 : freelist->first_available += 1;
228 : :
229 : 0 : freelist->entries[index].item = ptr;
230 : 0 : freelist->entries[index].destructor = destructor;
231 : :
232 : 0 : return 0;
233 : : }
234 : :
235 : : static int
236 : 260408 : cleanreturn(int retval, freelist_t *freelist)
237 : : {
238 : : int index;
239 : :
240 [ - + ]: 260408 : if (retval == 0) {
241 : : /* A failure occurred, therefore execute all of the cleanup
242 : : functions.
243 : : */
244 [ # # ]: 0 : for (index = 0; index < freelist->first_available; ++index) {
245 : 0 : freelist->entries[index].destructor(NULL,
246 : 0 : freelist->entries[index].item);
247 : : }
248 : : }
249 [ + + ]: 260408 : if (freelist->entries_malloced)
250 : 30 : PyMem_Free(freelist->entries);
251 : 260408 : return retval;
252 : : }
253 : :
254 : :
255 : : static int
256 : 130175 : vgetargs1_impl(PyObject *compat_args, PyObject *const *stack, Py_ssize_t nargs, const char *format,
257 : : va_list *p_va, int flags)
258 : : {
259 : : char msgbuf[256];
260 : : int levels[32];
261 : 130175 : const char *fname = NULL;
262 : 130175 : const char *message = NULL;
263 : 130175 : int min = -1;
264 : 130175 : int max = 0;
265 : 130175 : int level = 0;
266 : 130175 : int endfmt = 0;
267 : 130175 : const char *formatsave = format;
268 : : Py_ssize_t i;
269 : : const char *msg;
270 : 130175 : int compat = flags & FLAG_COMPAT;
271 : : freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
272 : : freelist_t freelist;
273 : :
274 : : assert(nargs == 0 || stack != NULL);
275 : :
276 : 130175 : freelist.entries = static_entries;
277 : 130175 : freelist.first_available = 0;
278 : 130175 : freelist.entries_malloced = 0;
279 : :
280 : 130175 : flags = flags & ~FLAG_COMPAT;
281 : :
282 [ + + ]: 486266 : while (endfmt == 0) {
283 : 356091 : int c = *format++;
284 [ - - + + : 356091 : switch (c) {
+ + + ]
285 : 0 : case '(':
286 [ # # ]: 0 : if (level == 0)
287 : 0 : max++;
288 : 0 : level++;
289 [ # # ]: 0 : if (level >= 30)
290 : 0 : Py_FatalError("too many tuple nesting levels "
291 : : "in argument format string");
292 : 0 : break;
293 : 0 : case ')':
294 [ # # ]: 0 : if (level == 0)
295 : 0 : Py_FatalError("excess ')' in getargs format");
296 : : else
297 : 0 : level--;
298 : 0 : break;
299 : 298 : case '\0':
300 : 298 : endfmt = 1;
301 : 298 : break;
302 : 129861 : case ':':
303 : 129861 : fname = format;
304 : 129861 : endfmt = 1;
305 : 129861 : break;
306 : 16 : case ';':
307 : 16 : message = format;
308 : 16 : endfmt = 1;
309 : 16 : break;
310 : 23513 : case '|':
311 [ + - ]: 23513 : if (level == 0)
312 : 23513 : min = max;
313 : 23513 : break;
314 : 202403 : default:
315 [ + - ]: 202403 : if (level == 0) {
316 [ + + ]: 202403 : if (Py_ISALPHA(c))
317 [ + - ]: 189815 : if (c != 'e') /* skip encoded */
318 : 189815 : max++;
319 : : }
320 : 202403 : break;
321 : : }
322 : : }
323 : :
324 [ - + ]: 130175 : if (level != 0)
325 : 0 : Py_FatalError(/* '(' */ "missing ')' in getargs format");
326 : :
327 [ + + ]: 130175 : if (min < 0)
328 : 106662 : min = max;
329 : :
330 : 130175 : format = formatsave;
331 : :
332 [ - + ]: 130175 : if (max > STATIC_FREELIST_ENTRIES) {
333 [ # # ]: 0 : freelist.entries = PyMem_NEW(freelistentry_t, max);
334 [ # # ]: 0 : if (freelist.entries == NULL) {
335 : 0 : PyErr_NoMemory();
336 : 0 : return 0;
337 : : }
338 : 0 : freelist.entries_malloced = 1;
339 : : }
340 : :
341 [ - + ]: 130175 : if (compat) {
342 [ # # ]: 0 : if (max == 0) {
343 [ # # ]: 0 : if (compat_args == NULL)
344 : 0 : return 1;
345 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
346 : : "%.200s%s takes no arguments",
347 : : fname==NULL ? "function" : fname,
348 : : fname==NULL ? "" : "()");
349 : 0 : return cleanreturn(0, &freelist);
350 : : }
351 [ # # # # ]: 0 : else if (min == 1 && max == 1) {
352 [ # # ]: 0 : if (compat_args == NULL) {
353 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
354 : : "%.200s%s takes at least one argument",
355 : : fname==NULL ? "function" : fname,
356 : : fname==NULL ? "" : "()");
357 : 0 : return cleanreturn(0, &freelist);
358 : : }
359 : 0 : msg = convertitem(compat_args, &format, p_va, flags, levels,
360 : : msgbuf, sizeof(msgbuf), &freelist);
361 [ # # ]: 0 : if (msg == NULL)
362 : 0 : return cleanreturn(1, &freelist);
363 : 0 : seterror(levels[0], msg, levels+1, fname, message);
364 : 0 : return cleanreturn(0, &freelist);
365 : : }
366 : : else {
367 : 0 : PyErr_SetString(PyExc_SystemError,
368 : : "old style getargs format uses new features");
369 : 0 : return cleanreturn(0, &freelist);
370 : : }
371 : : }
372 : :
373 [ + - - + ]: 130175 : if (nargs < min || max < nargs) {
374 [ # # ]: 0 : if (message == NULL)
375 [ # # # # : 0 : PyErr_Format(PyExc_TypeError,
# # # # ]
376 : : "%.150s%s takes %s %d argument%s (%zd given)",
377 : : fname==NULL ? "function" : fname,
378 : : fname==NULL ? "" : "()",
379 : : min==max ? "exactly"
380 [ # # ]: 0 : : nargs < min ? "at least" : "at most",
381 [ # # ]: 0 : nargs < min ? min : max,
382 [ # # ]: 0 : (nargs < min ? min : max) == 1 ? "" : "s",
383 : : nargs);
384 : : else
385 : 0 : PyErr_SetString(PyExc_TypeError, message);
386 : 0 : return cleanreturn(0, &freelist);
387 : : }
388 : :
389 [ + + ]: 273914 : for (i = 0; i < nargs; i++) {
390 [ + + ]: 143739 : if (*format == '|')
391 : 835 : format++;
392 : 143739 : msg = convertitem(stack[i], &format, p_va,
393 : : flags, levels, msgbuf,
394 : : sizeof(msgbuf), &freelist);
395 [ - + ]: 143739 : if (msg) {
396 : 0 : seterror(i+1, msg, levels, fname, message);
397 : 0 : return cleanreturn(0, &freelist);
398 : : }
399 : : }
400 : :
401 [ + + + + ]: 130175 : if (*format != '\0' && !Py_ISALPHA(*format) &&
402 [ + - ]: 129156 : *format != '(' &&
403 [ + + + + : 129156 : *format != '|' && *format != ':' && *format != ';') {
- + ]
404 : 0 : PyErr_Format(PyExc_SystemError,
405 : : "bad format string: %.200s", formatsave);
406 : 0 : return cleanreturn(0, &freelist);
407 : : }
408 : :
409 : 130175 : return cleanreturn(1, &freelist);
410 : : }
411 : :
412 : : static int
413 : 130174 : vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
414 : : {
415 : : PyObject **stack;
416 : : Py_ssize_t nargs;
417 : :
418 [ + - ]: 130174 : if (!(flags & FLAG_COMPAT)) {
419 : : assert(args != NULL);
420 : :
421 [ - + ]: 130174 : if (!PyTuple_Check(args)) {
422 : 0 : PyErr_SetString(PyExc_SystemError,
423 : : "new style getargs format but argument is not a tuple");
424 : 0 : return 0;
425 : : }
426 : :
427 : 130174 : stack = _PyTuple_ITEMS(args);
428 : 130174 : nargs = PyTuple_GET_SIZE(args);
429 : : }
430 : : else {
431 : 0 : stack = NULL;
432 : 0 : nargs = 0;
433 : : }
434 : :
435 : 130174 : return vgetargs1_impl(args, stack, nargs, format, p_va, flags);
436 : : }
437 : :
438 : :
439 : : static void
440 : 0 : seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,
441 : : const char *message)
442 : : {
443 : : char buf[512];
444 : : int i;
445 : 0 : char *p = buf;
446 : :
447 [ # # ]: 0 : if (PyErr_Occurred())
448 : 0 : return;
449 [ # # ]: 0 : else if (message == NULL) {
450 [ # # ]: 0 : if (fname != NULL) {
451 : 0 : PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
452 : 0 : p += strlen(p);
453 : : }
454 [ # # ]: 0 : if (iarg != 0) {
455 : 0 : PyOS_snprintf(p, sizeof(buf) - (p - buf),
456 : : "argument %zd", iarg);
457 : 0 : i = 0;
458 : 0 : p += strlen(p);
459 [ # # # # : 0 : while (i < 32 && levels[i] > 0 && (int)(p-buf) < 220) {
# # ]
460 : 0 : PyOS_snprintf(p, sizeof(buf) - (p - buf),
461 : 0 : ", item %d", levels[i]-1);
462 : 0 : p += strlen(p);
463 : 0 : i++;
464 : : }
465 : : }
466 : : else {
467 : 0 : PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
468 : 0 : p += strlen(p);
469 : : }
470 : 0 : PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
471 : 0 : message = buf;
472 : : }
473 [ # # ]: 0 : if (msg[0] == '(') {
474 : 0 : PyErr_SetString(PyExc_SystemError, message);
475 : : }
476 : : else {
477 : 0 : PyErr_SetString(PyExc_TypeError, message);
478 : : }
479 : : }
480 : :
481 : :
482 : : /* Convert a tuple argument.
483 : : On entry, *p_format points to the character _after_ the opening '('.
484 : : On successful exit, *p_format points to the closing ')'.
485 : : If successful:
486 : : *p_format and *p_va are updated,
487 : : *levels and *msgbuf are untouched,
488 : : and NULL is returned.
489 : : If the argument is invalid:
490 : : *p_format is unchanged,
491 : : *p_va is undefined,
492 : : *levels is a 0-terminated list of item numbers,
493 : : *msgbuf contains an error message, whose format is:
494 : : "must be <typename1>, not <typename2>", where:
495 : : <typename1> is the name of the expected type, and
496 : : <typename2> is the name of the actual type,
497 : : and msgbuf is returned.
498 : : */
499 : :
500 : : static const char *
501 : 0 : converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
502 : : int *levels, char *msgbuf, size_t bufsize, int toplevel,
503 : : freelist_t *freelist)
504 : : {
505 : 0 : int level = 0;
506 : 0 : int n = 0;
507 : 0 : const char *format = *p_format;
508 : : int i;
509 : : Py_ssize_t len;
510 : :
511 : 0 : for (;;) {
512 : 0 : int c = *format++;
513 [ # # ]: 0 : if (c == '(') {
514 [ # # ]: 0 : if (level == 0)
515 : 0 : n++;
516 : 0 : level++;
517 : : }
518 [ # # ]: 0 : else if (c == ')') {
519 [ # # ]: 0 : if (level == 0)
520 : 0 : break;
521 : 0 : level--;
522 : : }
523 [ # # # # : 0 : else if (c == ':' || c == ';' || c == '\0')
# # ]
524 : : break;
525 [ # # # # ]: 0 : else if (level == 0 && Py_ISALPHA(c))
526 : 0 : n++;
527 : : }
528 : :
529 [ # # # # ]: 0 : if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
530 : 0 : levels[0] = 0;
531 [ # # # # ]: 0 : PyOS_snprintf(msgbuf, bufsize,
532 : : toplevel ? "expected %d arguments, not %.50s" :
533 : : "must be %d-item sequence, not %.50s",
534 : : n,
535 : 0 : arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
536 : 0 : return msgbuf;
537 : : }
538 : :
539 : 0 : len = PySequence_Size(arg);
540 [ # # ]: 0 : if (len != n) {
541 : 0 : levels[0] = 0;
542 [ # # ]: 0 : if (toplevel) {
543 [ # # ]: 0 : PyOS_snprintf(msgbuf, bufsize,
544 : : "expected %d argument%s, not %zd",
545 : : n,
546 : : n == 1 ? "" : "s",
547 : : len);
548 : : }
549 : : else {
550 : 0 : PyOS_snprintf(msgbuf, bufsize,
551 : : "must be sequence of length %d, not %zd",
552 : : n, len);
553 : : }
554 : 0 : return msgbuf;
555 : : }
556 : :
557 : 0 : format = *p_format;
558 [ # # ]: 0 : for (i = 0; i < n; i++) {
559 : : const char *msg;
560 : : PyObject *item;
561 : 0 : item = PySequence_GetItem(arg, i);
562 [ # # ]: 0 : if (item == NULL) {
563 : 0 : PyErr_Clear();
564 : 0 : levels[0] = i+1;
565 : 0 : levels[1] = 0;
566 : 0 : strncpy(msgbuf, "is not retrievable", bufsize);
567 : 0 : return msgbuf;
568 : : }
569 : 0 : msg = convertitem(item, &format, p_va, flags, levels+1,
570 : : msgbuf, bufsize, freelist);
571 : : /* PySequence_GetItem calls tp->sq_item, which INCREFs */
572 : 0 : Py_XDECREF(item);
573 [ # # ]: 0 : if (msg != NULL) {
574 : 0 : levels[0] = i+1;
575 : 0 : return msg;
576 : : }
577 : : }
578 : :
579 : 0 : *p_format = format;
580 : 0 : return NULL;
581 : : }
582 : :
583 : :
584 : : /* Convert a single item. */
585 : :
586 : : static const char *
587 : 144805 : convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
588 : : int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist)
589 : : {
590 : : const char *msg;
591 : 144805 : const char *format = *p_format;
592 : :
593 [ - + ]: 144805 : if (*format == '(' /* ')' */) {
594 : 0 : format++;
595 : 0 : msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
596 : : bufsize, 0, freelist);
597 [ # # ]: 0 : if (msg == NULL)
598 : 0 : format++;
599 : : }
600 : : else {
601 : 144805 : msg = convertsimple(arg, &format, p_va, flags,
602 : : msgbuf, bufsize, freelist);
603 [ - + ]: 144805 : if (msg != NULL)
604 : 0 : levels[0] = 0;
605 : : }
606 [ + - ]: 144805 : if (msg == NULL)
607 : 144805 : *p_format = format;
608 : 144805 : return msg;
609 : : }
610 : :
611 : :
612 : :
613 : : /* Format an error message generated by convertsimple().
614 : : displayname must be UTF-8 encoded.
615 : : */
616 : :
617 : : void
618 : 0 : _PyArg_BadArgument(const char *fname, const char *displayname,
619 : : const char *expected, PyObject *arg)
620 : : {
621 [ # # ]: 0 : PyErr_Format(PyExc_TypeError,
622 : : "%.200s() %.200s must be %.50s, not %.50s",
623 : : fname, displayname, expected,
624 : 0 : arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
625 : 0 : }
626 : :
627 : : static const char *
628 : 0 : converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
629 : : {
630 : : assert(expected != NULL);
631 : : assert(arg != NULL);
632 [ # # ]: 0 : if (expected[0] == '(') {
633 : 0 : PyOS_snprintf(msgbuf, bufsize,
634 : : "%.100s", expected);
635 : : }
636 : : else {
637 [ # # ]: 0 : PyOS_snprintf(msgbuf, bufsize,
638 : : "must be %.50s, not %.50s", expected,
639 : 0 : arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
640 : : }
641 : 0 : return msgbuf;
642 : : }
643 : :
644 : : #define CONV_UNICODE "(unicode conversion error)"
645 : :
646 : : /* Convert a non-tuple argument. Return NULL if conversion went OK,
647 : : or a string with a message describing the failure. The message is
648 : : formatted as "must be <desired type>, not <actual type>".
649 : : When failing, an exception may or may not have been raised.
650 : : Don't call if a tuple is expected.
651 : :
652 : : When you add new format codes, please don't forget poor skipitem() below.
653 : : */
654 : :
655 : : static const char *
656 : 144805 : convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
657 : : char *msgbuf, size_t bufsize, freelist_t *freelist)
658 : : {
659 : : #define RETURN_ERR_OCCURRED return msgbuf
660 : : /* For # codes */
661 : : #define REQUIRE_PY_SSIZE_T_CLEAN \
662 : : if (!(flags & FLAG_SIZE_T)) { \
663 : : PyErr_SetString(PyExc_SystemError, \
664 : : "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \
665 : : RETURN_ERR_OCCURRED; \
666 : : }
667 : :
668 : 144805 : const char *format = *p_format;
669 : 144805 : char c = *format++;
670 : : const char *sarg;
671 : :
672 [ - - - - : 144805 : switch (c) {
+ - + - -
- + - - -
- - + - -
- - - + +
- - ]
673 : :
674 : 0 : case 'b': { /* unsigned byte -- very short int */
675 : 0 : char *p = va_arg(*p_va, char *);
676 : 0 : long ival = PyLong_AsLong(arg);
677 [ # # # # ]: 0 : if (ival == -1 && PyErr_Occurred())
678 : 0 : RETURN_ERR_OCCURRED;
679 [ # # ]: 0 : else if (ival < 0) {
680 : 0 : PyErr_SetString(PyExc_OverflowError,
681 : : "unsigned byte integer is less than minimum");
682 : 0 : RETURN_ERR_OCCURRED;
683 : : }
684 [ # # ]: 0 : else if (ival > UCHAR_MAX) {
685 : 0 : PyErr_SetString(PyExc_OverflowError,
686 : : "unsigned byte integer is greater than maximum");
687 : 0 : RETURN_ERR_OCCURRED;
688 : : }
689 : : else
690 : 0 : *p = (unsigned char) ival;
691 : 0 : break;
692 : : }
693 : :
694 : 0 : case 'B': {/* byte sized bitfield - both signed and unsigned
695 : : values allowed */
696 : 0 : char *p = va_arg(*p_va, char *);
697 : 0 : unsigned long ival = PyLong_AsUnsignedLongMask(arg);
698 [ # # # # ]: 0 : if (ival == (unsigned long)-1 && PyErr_Occurred())
699 : 0 : RETURN_ERR_OCCURRED;
700 : : else
701 : 0 : *p = (unsigned char) ival;
702 : 0 : break;
703 : : }
704 : :
705 : 0 : case 'h': {/* signed short int */
706 : 0 : short *p = va_arg(*p_va, short *);
707 : 0 : long ival = PyLong_AsLong(arg);
708 [ # # # # ]: 0 : if (ival == -1 && PyErr_Occurred())
709 : 0 : RETURN_ERR_OCCURRED;
710 [ # # ]: 0 : else if (ival < SHRT_MIN) {
711 : 0 : PyErr_SetString(PyExc_OverflowError,
712 : : "signed short integer is less than minimum");
713 : 0 : RETURN_ERR_OCCURRED;
714 : : }
715 [ # # ]: 0 : else if (ival > SHRT_MAX) {
716 : 0 : PyErr_SetString(PyExc_OverflowError,
717 : : "signed short integer is greater than maximum");
718 : 0 : RETURN_ERR_OCCURRED;
719 : : }
720 : : else
721 : 0 : *p = (short) ival;
722 : 0 : break;
723 : : }
724 : :
725 : 0 : case 'H': { /* short int sized bitfield, both signed and
726 : : unsigned allowed */
727 : 0 : unsigned short *p = va_arg(*p_va, unsigned short *);
728 : 0 : unsigned long ival = PyLong_AsUnsignedLongMask(arg);
729 [ # # # # ]: 0 : if (ival == (unsigned long)-1 && PyErr_Occurred())
730 : 0 : RETURN_ERR_OCCURRED;
731 : : else
732 : 0 : *p = (unsigned short) ival;
733 : 0 : break;
734 : : }
735 : :
736 : 6 : case 'i': {/* signed int */
737 : 6 : int *p = va_arg(*p_va, int *);
738 : 6 : long ival = PyLong_AsLong(arg);
739 [ + + - + ]: 6 : if (ival == -1 && PyErr_Occurred())
740 : 0 : RETURN_ERR_OCCURRED;
741 [ - + ]: 6 : else if (ival > INT_MAX) {
742 : 0 : PyErr_SetString(PyExc_OverflowError,
743 : : "signed integer is greater than maximum");
744 : 0 : RETURN_ERR_OCCURRED;
745 : : }
746 [ - + ]: 6 : else if (ival < INT_MIN) {
747 : 0 : PyErr_SetString(PyExc_OverflowError,
748 : : "signed integer is less than minimum");
749 : 0 : RETURN_ERR_OCCURRED;
750 : : }
751 : : else
752 : 6 : *p = ival;
753 : 6 : break;
754 : : }
755 : :
756 : 0 : case 'I': { /* int sized bitfield, both signed and
757 : : unsigned allowed */
758 : 0 : unsigned int *p = va_arg(*p_va, unsigned int *);
759 : 0 : unsigned long ival = PyLong_AsUnsignedLongMask(arg);
760 [ # # # # ]: 0 : if (ival == (unsigned long)-1 && PyErr_Occurred())
761 : 0 : RETURN_ERR_OCCURRED;
762 : : else
763 : 0 : *p = (unsigned int) ival;
764 : 0 : break;
765 : : }
766 : :
767 : 348 : case 'n': /* Py_ssize_t */
768 : : {
769 : : PyObject *iobj;
770 : 348 : Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
771 : 348 : Py_ssize_t ival = -1;
772 : 348 : iobj = _PyNumber_Index(arg);
773 [ + - ]: 348 : if (iobj != NULL) {
774 : 348 : ival = PyLong_AsSsize_t(iobj);
775 : 348 : Py_DECREF(iobj);
776 : : }
777 [ - + - - ]: 348 : if (ival == -1 && PyErr_Occurred())
778 : 0 : RETURN_ERR_OCCURRED;
779 : 348 : *p = ival;
780 : 348 : break;
781 : : }
782 : 0 : case 'l': {/* long int */
783 : 0 : long *p = va_arg(*p_va, long *);
784 : 0 : long ival = PyLong_AsLong(arg);
785 [ # # # # ]: 0 : if (ival == -1 && PyErr_Occurred())
786 : 0 : RETURN_ERR_OCCURRED;
787 : : else
788 : 0 : *p = ival;
789 : 0 : break;
790 : : }
791 : :
792 : 0 : case 'k': { /* long sized bitfield */
793 : 0 : unsigned long *p = va_arg(*p_va, unsigned long *);
794 : : unsigned long ival;
795 [ # # ]: 0 : if (PyLong_Check(arg))
796 : 0 : ival = PyLong_AsUnsignedLongMask(arg);
797 : : else
798 : 0 : return converterr("int", arg, msgbuf, bufsize);
799 : 0 : *p = ival;
800 : 0 : break;
801 : : }
802 : :
803 : 0 : case 'L': {/* long long */
804 : 0 : long long *p = va_arg( *p_va, long long * );
805 : 0 : long long ival = PyLong_AsLongLong(arg);
806 [ # # # # ]: 0 : if (ival == (long long)-1 && PyErr_Occurred())
807 : 0 : RETURN_ERR_OCCURRED;
808 : : else
809 : 0 : *p = ival;
810 : 0 : break;
811 : : }
812 : :
813 : 8 : case 'K': { /* long long sized bitfield */
814 : 8 : unsigned long long *p = va_arg(*p_va, unsigned long long *);
815 : : unsigned long long ival;
816 [ + - ]: 8 : if (PyLong_Check(arg))
817 : 8 : ival = PyLong_AsUnsignedLongLongMask(arg);
818 : : else
819 : 0 : return converterr("int", arg, msgbuf, bufsize);
820 : 8 : *p = ival;
821 : 8 : break;
822 : : }
823 : :
824 : 0 : case 'f': {/* float */
825 : 0 : float *p = va_arg(*p_va, float *);
826 : 0 : double dval = PyFloat_AsDouble(arg);
827 [ # # # # ]: 0 : if (dval == -1.0 && PyErr_Occurred())
828 : 0 : RETURN_ERR_OCCURRED;
829 : : else
830 : 0 : *p = (float) dval;
831 : 0 : break;
832 : : }
833 : :
834 : 0 : case 'd': {/* double */
835 : 0 : double *p = va_arg(*p_va, double *);
836 : 0 : double dval = PyFloat_AsDouble(arg);
837 [ # # # # ]: 0 : if (dval == -1.0 && PyErr_Occurred())
838 : 0 : RETURN_ERR_OCCURRED;
839 : : else
840 : 0 : *p = dval;
841 : 0 : break;
842 : : }
843 : :
844 : 0 : case 'D': {/* complex double */
845 : 0 : Py_complex *p = va_arg(*p_va, Py_complex *);
846 : : Py_complex cval;
847 : 0 : cval = PyComplex_AsCComplex(arg);
848 [ # # ]: 0 : if (PyErr_Occurred())
849 : 0 : RETURN_ERR_OCCURRED;
850 : : else
851 : 0 : *p = cval;
852 : 0 : break;
853 : : }
854 : :
855 : 0 : case 'c': {/* char */
856 : 0 : char *p = va_arg(*p_va, char *);
857 [ # # # # ]: 0 : if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1)
858 : 0 : *p = PyBytes_AS_STRING(arg)[0];
859 [ # # # # ]: 0 : else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1)
860 : 0 : *p = PyByteArray_AS_STRING(arg)[0];
861 : : else
862 : 0 : return converterr("a byte string of length 1", arg, msgbuf, bufsize);
863 : 0 : break;
864 : : }
865 : :
866 : 0 : case 'C': {/* unicode char */
867 : 0 : int *p = va_arg(*p_va, int *);
868 : : int kind;
869 : : const void *data;
870 : :
871 [ # # ]: 0 : if (!PyUnicode_Check(arg))
872 : 0 : return converterr("a unicode character", arg, msgbuf, bufsize);
873 : :
874 [ # # ]: 0 : if (PyUnicode_READY(arg))
875 : 0 : RETURN_ERR_OCCURRED;
876 : :
877 [ # # ]: 0 : if (PyUnicode_GET_LENGTH(arg) != 1)
878 : 0 : return converterr("a unicode character", arg, msgbuf, bufsize);
879 : :
880 : 0 : kind = PyUnicode_KIND(arg);
881 : 0 : data = PyUnicode_DATA(arg);
882 : 0 : *p = PyUnicode_READ(kind, data, 0);
883 : 0 : break;
884 : : }
885 : :
886 : 61 : case 'p': {/* boolean *p*redicate */
887 : 61 : int *p = va_arg(*p_va, int *);
888 : 61 : int val = PyObject_IsTrue(arg);
889 [ + + ]: 61 : if (val > 0)
890 : 26 : *p = 1;
891 [ + - ]: 35 : else if (val == 0)
892 : 35 : *p = 0;
893 : : else
894 : 0 : RETURN_ERR_OCCURRED;
895 : 61 : break;
896 : : }
897 : :
898 : : /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
899 : : need to be cleaned up! */
900 : :
901 : 0 : case 'y': {/* any bytes-like object */
902 : 0 : void **p = (void **)va_arg(*p_va, char **);
903 : : const char *buf;
904 : : Py_ssize_t count;
905 [ # # ]: 0 : if (*format == '*') {
906 [ # # ]: 0 : if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
907 : 0 : return converterr(buf, arg, msgbuf, bufsize);
908 : 0 : format++;
909 [ # # ]: 0 : if (addcleanup(p, freelist, cleanup_buffer)) {
910 : 0 : return converterr(
911 : : "(cleanup problem)",
912 : : arg, msgbuf, bufsize);
913 : : }
914 : 0 : break;
915 : : }
916 : 0 : count = convertbuffer(arg, (const void **)p, &buf);
917 [ # # ]: 0 : if (count < 0)
918 : 0 : return converterr(buf, arg, msgbuf, bufsize);
919 [ # # ]: 0 : if (*format == '#') {
920 [ # # ]: 0 : REQUIRE_PY_SSIZE_T_CLEAN;
921 : 0 : Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
922 : 0 : *psize = count;
923 : 0 : format++;
924 : : } else {
925 [ # # ]: 0 : if (strlen(*p) != (size_t)count) {
926 : 0 : PyErr_SetString(PyExc_ValueError, "embedded null byte");
927 : 0 : RETURN_ERR_OCCURRED;
928 : : }
929 : : }
930 : 0 : break;
931 : : }
932 : :
933 : 0 : case 's': /* text string or bytes-like object */
934 : : case 'z': /* text string, bytes-like object or None */
935 : : {
936 [ # # ]: 0 : if (*format == '*') {
937 : : /* "s*" or "z*" */
938 : 0 : Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
939 : :
940 [ # # # # ]: 0 : if (c == 'z' && arg == Py_None)
941 : 0 : PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
942 [ # # ]: 0 : else if (PyUnicode_Check(arg)) {
943 : : Py_ssize_t len;
944 : 0 : sarg = PyUnicode_AsUTF8AndSize(arg, &len);
945 [ # # ]: 0 : if (sarg == NULL)
946 : 0 : return converterr(CONV_UNICODE,
947 : : arg, msgbuf, bufsize);
948 : 0 : PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0);
949 : : }
950 : : else { /* any bytes-like object */
951 : : const char *buf;
952 [ # # ]: 0 : if (getbuffer(arg, p, &buf) < 0)
953 : 0 : return converterr(buf, arg, msgbuf, bufsize);
954 : : }
955 [ # # ]: 0 : if (addcleanup(p, freelist, cleanup_buffer)) {
956 : 0 : return converterr(
957 : : "(cleanup problem)",
958 : : arg, msgbuf, bufsize);
959 : : }
960 : 0 : format++;
961 [ # # ]: 0 : } else if (*format == '#') { /* a string or read-only bytes-like object */
962 : : /* "s#" or "z#" */
963 : 0 : const void **p = (const void **)va_arg(*p_va, const char **);
964 [ # # ]: 0 : REQUIRE_PY_SSIZE_T_CLEAN;
965 : 0 : Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
966 : :
967 [ # # # # ]: 0 : if (c == 'z' && arg == Py_None) {
968 : 0 : *p = NULL;
969 : 0 : *psize = 0;
970 : : }
971 [ # # ]: 0 : else if (PyUnicode_Check(arg)) {
972 : : Py_ssize_t len;
973 : 0 : sarg = PyUnicode_AsUTF8AndSize(arg, &len);
974 [ # # ]: 0 : if (sarg == NULL)
975 : 0 : return converterr(CONV_UNICODE,
976 : : arg, msgbuf, bufsize);
977 : 0 : *p = sarg;
978 : 0 : *psize = len;
979 : : }
980 : : else { /* read-only bytes-like object */
981 : : /* XXX Really? */
982 : : const char *buf;
983 : 0 : Py_ssize_t count = convertbuffer(arg, p, &buf);
984 [ # # ]: 0 : if (count < 0)
985 : 0 : return converterr(buf, arg, msgbuf, bufsize);
986 : 0 : *psize = count;
987 : : }
988 : 0 : format++;
989 : : } else {
990 : : /* "s" or "z" */
991 : 0 : const char **p = va_arg(*p_va, const char **);
992 : : Py_ssize_t len;
993 : 0 : sarg = NULL;
994 : :
995 [ # # # # ]: 0 : if (c == 'z' && arg == Py_None)
996 : 0 : *p = NULL;
997 [ # # ]: 0 : else if (PyUnicode_Check(arg)) {
998 : 0 : sarg = PyUnicode_AsUTF8AndSize(arg, &len);
999 [ # # ]: 0 : if (sarg == NULL)
1000 : 0 : return converterr(CONV_UNICODE,
1001 : : arg, msgbuf, bufsize);
1002 [ # # ]: 0 : if (strlen(sarg) != (size_t)len) {
1003 : 0 : PyErr_SetString(PyExc_ValueError, "embedded null character");
1004 : 0 : RETURN_ERR_OCCURRED;
1005 : : }
1006 : 0 : *p = sarg;
1007 : : }
1008 : : else
1009 [ # # ]: 0 : return converterr(c == 'z' ? "str or None" : "str",
1010 : : arg, msgbuf, bufsize);
1011 : : }
1012 : 0 : break;
1013 : : }
1014 : :
1015 : 0 : case 'e': {/* encoded string */
1016 : : char **buffer;
1017 : : const char *encoding;
1018 : : PyObject *s;
1019 : : int recode_strings;
1020 : : Py_ssize_t size;
1021 : : const char *ptr;
1022 : :
1023 : : /* Get 'e' parameter: the encoding name */
1024 : 0 : encoding = (const char *)va_arg(*p_va, const char *);
1025 [ # # ]: 0 : if (encoding == NULL)
1026 : 0 : encoding = PyUnicode_GetDefaultEncoding();
1027 : :
1028 : : /* Get output buffer parameter:
1029 : : 's' (recode all objects via Unicode) or
1030 : : 't' (only recode non-string objects)
1031 : : */
1032 [ # # ]: 0 : if (*format == 's')
1033 : 0 : recode_strings = 1;
1034 [ # # ]: 0 : else if (*format == 't')
1035 : 0 : recode_strings = 0;
1036 : : else
1037 : 0 : return converterr(
1038 : : "(unknown parser marker combination)",
1039 : : arg, msgbuf, bufsize);
1040 : 0 : buffer = (char **)va_arg(*p_va, char **);
1041 : 0 : format++;
1042 [ # # ]: 0 : if (buffer == NULL)
1043 : 0 : return converterr("(buffer is NULL)",
1044 : : arg, msgbuf, bufsize);
1045 : :
1046 : : /* Encode object */
1047 [ # # # # ]: 0 : if (!recode_strings &&
1048 [ # # ]: 0 : (PyBytes_Check(arg) || PyByteArray_Check(arg))) {
1049 : 0 : s = Py_NewRef(arg);
1050 [ # # ]: 0 : if (PyBytes_Check(arg)) {
1051 : 0 : size = PyBytes_GET_SIZE(s);
1052 : 0 : ptr = PyBytes_AS_STRING(s);
1053 : : }
1054 : : else {
1055 : 0 : size = PyByteArray_GET_SIZE(s);
1056 : 0 : ptr = PyByteArray_AS_STRING(s);
1057 : : }
1058 : : }
1059 [ # # ]: 0 : else if (PyUnicode_Check(arg)) {
1060 : : /* Encode object; use default error handling */
1061 : 0 : s = PyUnicode_AsEncodedString(arg,
1062 : : encoding,
1063 : : NULL);
1064 [ # # ]: 0 : if (s == NULL)
1065 : 0 : return converterr("(encoding failed)",
1066 : : arg, msgbuf, bufsize);
1067 : : assert(PyBytes_Check(s));
1068 : 0 : size = PyBytes_GET_SIZE(s);
1069 : 0 : ptr = PyBytes_AS_STRING(s);
1070 [ # # ]: 0 : if (ptr == NULL)
1071 : 0 : ptr = "";
1072 : : }
1073 : : else {
1074 [ # # ]: 0 : return converterr(
1075 : : recode_strings ? "str" : "str, bytes or bytearray",
1076 : : arg, msgbuf, bufsize);
1077 : : }
1078 : :
1079 : : /* Write output; output is guaranteed to be 0-terminated */
1080 [ # # ]: 0 : if (*format == '#') {
1081 : : /* Using buffer length parameter '#':
1082 : :
1083 : : - if *buffer is NULL, a new buffer of the
1084 : : needed size is allocated and the data
1085 : : copied into it; *buffer is updated to point
1086 : : to the new buffer; the caller is
1087 : : responsible for PyMem_Free()ing it after
1088 : : usage
1089 : :
1090 : : - if *buffer is not NULL, the data is
1091 : : copied to *buffer; *buffer_len has to be
1092 : : set to the size of the buffer on input;
1093 : : buffer overflow is signalled with an error;
1094 : : buffer has to provide enough room for the
1095 : : encoded string plus the trailing 0-byte
1096 : :
1097 : : - in both cases, *buffer_len is updated to
1098 : : the size of the buffer /excluding/ the
1099 : : trailing 0-byte
1100 : :
1101 : : */
1102 [ # # ]: 0 : REQUIRE_PY_SSIZE_T_CLEAN;
1103 : 0 : Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
1104 : :
1105 : 0 : format++;
1106 [ # # ]: 0 : if (psize == NULL) {
1107 : 0 : Py_DECREF(s);
1108 : 0 : return converterr(
1109 : : "(buffer_len is NULL)",
1110 : : arg, msgbuf, bufsize);
1111 : : }
1112 [ # # ]: 0 : if (*buffer == NULL) {
1113 [ # # ]: 0 : *buffer = PyMem_NEW(char, size + 1);
1114 [ # # ]: 0 : if (*buffer == NULL) {
1115 : 0 : Py_DECREF(s);
1116 : 0 : PyErr_NoMemory();
1117 : 0 : RETURN_ERR_OCCURRED;
1118 : : }
1119 [ # # ]: 0 : if (addcleanup(buffer, freelist, cleanup_ptr)) {
1120 : 0 : Py_DECREF(s);
1121 : 0 : return converterr(
1122 : : "(cleanup problem)",
1123 : : arg, msgbuf, bufsize);
1124 : : }
1125 : : } else {
1126 [ # # ]: 0 : if (size + 1 > *psize) {
1127 : 0 : Py_DECREF(s);
1128 : 0 : PyErr_Format(PyExc_ValueError,
1129 : : "encoded string too long "
1130 : : "(%zd, maximum length %zd)",
1131 : 0 : (Py_ssize_t)size, (Py_ssize_t)(*psize - 1));
1132 : 0 : RETURN_ERR_OCCURRED;
1133 : : }
1134 : : }
1135 : 0 : memcpy(*buffer, ptr, size+1);
1136 : :
1137 : 0 : *psize = size;
1138 : : }
1139 : : else {
1140 : : /* Using a 0-terminated buffer:
1141 : :
1142 : : - the encoded string has to be 0-terminated
1143 : : for this variant to work; if it is not, an
1144 : : error raised
1145 : :
1146 : : - a new buffer of the needed size is
1147 : : allocated and the data copied into it;
1148 : : *buffer is updated to point to the new
1149 : : buffer; the caller is responsible for
1150 : : PyMem_Free()ing it after usage
1151 : :
1152 : : */
1153 [ # # ]: 0 : if ((Py_ssize_t)strlen(ptr) != size) {
1154 : 0 : Py_DECREF(s);
1155 : 0 : return converterr(
1156 : : "encoded string without null bytes",
1157 : : arg, msgbuf, bufsize);
1158 : : }
1159 [ # # ]: 0 : *buffer = PyMem_NEW(char, size + 1);
1160 [ # # ]: 0 : if (*buffer == NULL) {
1161 : 0 : Py_DECREF(s);
1162 : 0 : PyErr_NoMemory();
1163 : 0 : RETURN_ERR_OCCURRED;
1164 : : }
1165 [ # # ]: 0 : if (addcleanup(buffer, freelist, cleanup_ptr)) {
1166 : 0 : Py_DECREF(s);
1167 : 0 : return converterr("(cleanup problem)",
1168 : : arg, msgbuf, bufsize);
1169 : : }
1170 : 0 : memcpy(*buffer, ptr, size+1);
1171 : : }
1172 : 0 : Py_DECREF(s);
1173 : 0 : break;
1174 : : }
1175 : :
1176 : 0 : case 'S': { /* PyBytes object */
1177 : 0 : PyObject **p = va_arg(*p_va, PyObject **);
1178 [ # # ]: 0 : if (PyBytes_Check(arg))
1179 : 0 : *p = arg;
1180 : : else
1181 : 0 : return converterr("bytes", arg, msgbuf, bufsize);
1182 : 0 : break;
1183 : : }
1184 : :
1185 : 0 : case 'Y': { /* PyByteArray object */
1186 : 0 : PyObject **p = va_arg(*p_va, PyObject **);
1187 [ # # ]: 0 : if (PyByteArray_Check(arg))
1188 : 0 : *p = arg;
1189 : : else
1190 : 0 : return converterr("bytearray", arg, msgbuf, bufsize);
1191 : 0 : break;
1192 : : }
1193 : :
1194 : 6595 : case 'U': { /* PyUnicode object */
1195 : 6595 : PyObject **p = va_arg(*p_va, PyObject **);
1196 [ + - ]: 6595 : if (PyUnicode_Check(arg)) {
1197 [ - + ]: 6595 : if (PyUnicode_READY(arg) == -1)
1198 : 0 : RETURN_ERR_OCCURRED;
1199 : 6595 : *p = arg;
1200 : : }
1201 : : else
1202 : 0 : return converterr("str", arg, msgbuf, bufsize);
1203 : 6595 : break;
1204 : : }
1205 : :
1206 : 137787 : case 'O': { /* object */
1207 : : PyTypeObject *type;
1208 : : PyObject **p;
1209 [ + + ]: 137787 : if (*format == '!') {
1210 : 12588 : type = va_arg(*p_va, PyTypeObject*);
1211 : 12588 : p = va_arg(*p_va, PyObject **);
1212 : 12588 : format++;
1213 [ + - ]: 12588 : if (PyType_IsSubtype(Py_TYPE(arg), type))
1214 : 12588 : *p = arg;
1215 : : else
1216 : 0 : return converterr(type->tp_name, arg, msgbuf, bufsize);
1217 : :
1218 : : }
1219 [ - + ]: 125199 : else if (*format == '&') {
1220 : : typedef int (*converter)(PyObject *, void *);
1221 : 0 : converter convert = va_arg(*p_va, converter);
1222 : 0 : void *addr = va_arg(*p_va, void *);
1223 : : int res;
1224 : 0 : format++;
1225 [ # # ]: 0 : if (! (res = (*convert)(arg, addr)))
1226 : 0 : return converterr("(unspecified)",
1227 : : arg, msgbuf, bufsize);
1228 [ # # # # ]: 0 : if (res == Py_CLEANUP_SUPPORTED &&
1229 : 0 : addcleanup(addr, freelist, convert) == -1)
1230 : 0 : return converterr("(cleanup problem)",
1231 : : arg, msgbuf, bufsize);
1232 : : }
1233 : : else {
1234 : 125199 : p = va_arg(*p_va, PyObject **);
1235 : 125199 : *p = arg;
1236 : : }
1237 : 137787 : break;
1238 : : }
1239 : :
1240 : :
1241 : 0 : case 'w': { /* "w*": memory buffer, read-write access */
1242 : 0 : void **p = va_arg(*p_va, void **);
1243 : :
1244 [ # # ]: 0 : if (*format != '*')
1245 : 0 : return converterr(
1246 : : "(invalid use of 'w' format character)",
1247 : : arg, msgbuf, bufsize);
1248 : 0 : format++;
1249 : :
1250 : : /* Caller is interested in Py_buffer, and the object
1251 : : supports it directly. */
1252 [ # # ]: 0 : if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
1253 : 0 : PyErr_Clear();
1254 : 0 : return converterr("read-write bytes-like object",
1255 : : arg, msgbuf, bufsize);
1256 : : }
1257 [ # # ]: 0 : if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) {
1258 : 0 : PyBuffer_Release((Py_buffer*)p);
1259 : 0 : return converterr("contiguous buffer", arg, msgbuf, bufsize);
1260 : : }
1261 [ # # ]: 0 : if (addcleanup(p, freelist, cleanup_buffer)) {
1262 : 0 : return converterr(
1263 : : "(cleanup problem)",
1264 : : arg, msgbuf, bufsize);
1265 : : }
1266 : 0 : break;
1267 : : }
1268 : :
1269 : 0 : default:
1270 : 0 : return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
1271 : :
1272 : : }
1273 : :
1274 : 144805 : *p_format = format;
1275 : 144805 : return NULL;
1276 : :
1277 : : #undef REQUIRE_PY_SSIZE_T_CLEAN
1278 : : #undef RETURN_ERR_OCCURRED
1279 : : }
1280 : :
1281 : : static Py_ssize_t
1282 : 0 : convertbuffer(PyObject *arg, const void **p, const char **errmsg)
1283 : : {
1284 : 0 : PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;
1285 : : Py_ssize_t count;
1286 : : Py_buffer view;
1287 : :
1288 : 0 : *errmsg = NULL;
1289 : 0 : *p = NULL;
1290 [ # # # # ]: 0 : if (pb != NULL && pb->bf_releasebuffer != NULL) {
1291 : 0 : *errmsg = "read-only bytes-like object";
1292 : 0 : return -1;
1293 : : }
1294 : :
1295 [ # # ]: 0 : if (getbuffer(arg, &view, errmsg) < 0)
1296 : 0 : return -1;
1297 : 0 : count = view.len;
1298 : 0 : *p = view.buf;
1299 : 0 : PyBuffer_Release(&view);
1300 : 0 : return count;
1301 : : }
1302 : :
1303 : : static int
1304 : 0 : getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg)
1305 : : {
1306 [ # # ]: 0 : if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
1307 : 0 : *errmsg = "bytes-like object";
1308 : 0 : return -1;
1309 : : }
1310 [ # # ]: 0 : if (!PyBuffer_IsContiguous(view, 'C')) {
1311 : 0 : PyBuffer_Release(view);
1312 : 0 : *errmsg = "contiguous buffer";
1313 : 0 : return -1;
1314 : : }
1315 : 0 : return 0;
1316 : : }
1317 : :
1318 : : /* Support for keyword arguments donated by
1319 : : Geoff Philbrick <philbric@delphi.hks.com> */
1320 : :
1321 : : /* Return false (0) for error, else true. */
1322 : : int
1323 : 115790 : PyArg_ParseTupleAndKeywords(PyObject *args,
1324 : : PyObject *keywords,
1325 : : const char *format,
1326 : : char **kwlist, ...)
1327 : : {
1328 : : int retval;
1329 : : va_list va;
1330 : :
1331 [ + - + - : 115790 : if ((args == NULL || !PyTuple_Check(args)) ||
+ + ]
1332 [ + - + - ]: 115790 : (keywords != NULL && !PyDict_Check(keywords)) ||
1333 [ - + ]: 115790 : format == NULL ||
1334 : : kwlist == NULL)
1335 : : {
1336 : 0 : PyErr_BadInternalCall();
1337 : 0 : return 0;
1338 : : }
1339 : :
1340 : 115790 : va_start(va, kwlist);
1341 : 115790 : retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
1342 : 115790 : va_end(va);
1343 : 115790 : return retval;
1344 : : }
1345 : :
1346 : : PyAPI_FUNC(int)
1347 : 14443 : _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
1348 : : PyObject *keywords,
1349 : : const char *format,
1350 : : char **kwlist, ...)
1351 : : {
1352 : : int retval;
1353 : : va_list va;
1354 : :
1355 [ + - + - : 14443 : if ((args == NULL || !PyTuple_Check(args)) ||
+ + ]
1356 [ + - + - ]: 14443 : (keywords != NULL && !PyDict_Check(keywords)) ||
1357 [ - + ]: 14443 : format == NULL ||
1358 : : kwlist == NULL)
1359 : : {
1360 : 0 : PyErr_BadInternalCall();
1361 : 0 : return 0;
1362 : : }
1363 : :
1364 : 14443 : va_start(va, kwlist);
1365 : 14443 : retval = vgetargskeywords(args, keywords, format,
1366 : : kwlist, &va, FLAG_SIZE_T);
1367 : 14443 : va_end(va);
1368 : 14443 : return retval;
1369 : : }
1370 : :
1371 : :
1372 : : int
1373 : 0 : PyArg_VaParseTupleAndKeywords(PyObject *args,
1374 : : PyObject *keywords,
1375 : : const char *format,
1376 : : char **kwlist, va_list va)
1377 : : {
1378 : : int retval;
1379 : : va_list lva;
1380 : :
1381 [ # # # # : 0 : if ((args == NULL || !PyTuple_Check(args)) ||
# # ]
1382 [ # # # # ]: 0 : (keywords != NULL && !PyDict_Check(keywords)) ||
1383 [ # # ]: 0 : format == NULL ||
1384 : : kwlist == NULL)
1385 : : {
1386 : 0 : PyErr_BadInternalCall();
1387 : 0 : return 0;
1388 : : }
1389 : :
1390 : 0 : va_copy(lva, va);
1391 : :
1392 : 0 : retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
1393 : 0 : va_end(lva);
1394 : 0 : return retval;
1395 : : }
1396 : :
1397 : : PyAPI_FUNC(int)
1398 : 0 : _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
1399 : : PyObject *keywords,
1400 : : const char *format,
1401 : : char **kwlist, va_list va)
1402 : : {
1403 : : int retval;
1404 : : va_list lva;
1405 : :
1406 [ # # # # : 0 : if ((args == NULL || !PyTuple_Check(args)) ||
# # ]
1407 [ # # # # ]: 0 : (keywords != NULL && !PyDict_Check(keywords)) ||
1408 [ # # ]: 0 : format == NULL ||
1409 : : kwlist == NULL)
1410 : : {
1411 : 0 : PyErr_BadInternalCall();
1412 : 0 : return 0;
1413 : : }
1414 : :
1415 : 0 : va_copy(lva, va);
1416 : :
1417 : 0 : retval = vgetargskeywords(args, keywords, format,
1418 : : kwlist, &lva, FLAG_SIZE_T);
1419 : 0 : va_end(lva);
1420 : 0 : return retval;
1421 : : }
1422 : :
1423 : : PyAPI_FUNC(int)
1424 : 0 : _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
1425 : : struct _PyArg_Parser *parser, ...)
1426 : : {
1427 : : int retval;
1428 : : va_list va;
1429 : :
1430 : 0 : va_start(va, parser);
1431 : 0 : retval = vgetargskeywordsfast(args, keywords, parser, &va, 0);
1432 : 0 : va_end(va);
1433 : 0 : return retval;
1434 : : }
1435 : :
1436 : : PyAPI_FUNC(int)
1437 : 0 : _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
1438 : : struct _PyArg_Parser *parser, ...)
1439 : : {
1440 : : int retval;
1441 : : va_list va;
1442 : :
1443 : 0 : va_start(va, parser);
1444 : 0 : retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T);
1445 : 0 : va_end(va);
1446 : 0 : return retval;
1447 : : }
1448 : :
1449 : : PyAPI_FUNC(int)
1450 : 0 : _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
1451 : : struct _PyArg_Parser *parser, ...)
1452 : : {
1453 : : int retval;
1454 : : va_list va;
1455 : :
1456 : 0 : va_start(va, parser);
1457 : 0 : retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0);
1458 : 0 : va_end(va);
1459 : 0 : return retval;
1460 : : }
1461 : :
1462 : : PyAPI_FUNC(int)
1463 : 0 : _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
1464 : : struct _PyArg_Parser *parser, ...)
1465 : : {
1466 : : int retval;
1467 : : va_list va;
1468 : :
1469 : 0 : va_start(va, parser);
1470 : 0 : retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T);
1471 : 0 : va_end(va);
1472 : 0 : return retval;
1473 : : }
1474 : :
1475 : :
1476 : : PyAPI_FUNC(int)
1477 : 0 : _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
1478 : : struct _PyArg_Parser *parser, va_list va)
1479 : : {
1480 : : int retval;
1481 : : va_list lva;
1482 : :
1483 : 0 : va_copy(lva, va);
1484 : :
1485 : 0 : retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0);
1486 : 0 : va_end(lva);
1487 : 0 : return retval;
1488 : : }
1489 : :
1490 : : PyAPI_FUNC(int)
1491 : 0 : _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
1492 : : struct _PyArg_Parser *parser, va_list va)
1493 : : {
1494 : : int retval;
1495 : : va_list lva;
1496 : :
1497 : 0 : va_copy(lva, va);
1498 : :
1499 : 0 : retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T);
1500 : 0 : va_end(lva);
1501 : 0 : return retval;
1502 : : }
1503 : :
1504 : : static void
1505 : 0 : error_unexpected_keyword_arg(PyObject *kwargs, PyObject *kwnames, PyObject *kwtuple, const char *fname)
1506 : : {
1507 : : /* make sure there are no extraneous keyword arguments */
1508 : 0 : Py_ssize_t j = 0;
1509 : 0 : while (1) {
1510 : : PyObject *keyword;
1511 [ # # ]: 0 : if (kwargs != NULL) {
1512 [ # # ]: 0 : if (!PyDict_Next(kwargs, &j, &keyword, NULL))
1513 : 0 : break;
1514 : : }
1515 : : else {
1516 [ # # ]: 0 : if (j >= PyTuple_GET_SIZE(kwnames))
1517 : 0 : break;
1518 : 0 : keyword = PyTuple_GET_ITEM(kwnames, j);
1519 : 0 : j++;
1520 : : }
1521 [ # # ]: 0 : if (!PyUnicode_Check(keyword)) {
1522 : 0 : PyErr_SetString(PyExc_TypeError,
1523 : : "keywords must be strings");
1524 : 0 : return;
1525 : : }
1526 : :
1527 : 0 : int match = PySequence_Contains(kwtuple, keyword);
1528 [ # # ]: 0 : if (match <= 0) {
1529 [ # # ]: 0 : if (!match) {
1530 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
1531 : : "'%S' is an invalid keyword "
1532 : : "argument for %.200s%s",
1533 : : keyword,
1534 : : (fname == NULL) ? "this function" : fname,
1535 : : (fname == NULL) ? "" : "()");
1536 : : }
1537 : 0 : return;
1538 : : }
1539 : : }
1540 : : /* Something wrong happened. There are extraneous keyword arguments,
1541 : : * but we don't know what. And we don't bother. */
1542 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
1543 : : "invalid keyword argument for %.200s%s",
1544 : : (fname == NULL) ? "this function" : fname,
1545 : : (fname == NULL) ? "" : "()");
1546 : : }
1547 : :
1548 : : int
1549 : 124 : PyArg_ValidateKeywordArguments(PyObject *kwargs)
1550 : : {
1551 [ - + ]: 124 : if (!PyDict_Check(kwargs)) {
1552 : 0 : PyErr_BadInternalCall();
1553 : 0 : return 0;
1554 : : }
1555 [ - + ]: 124 : if (!_PyDict_HasOnlyStringKeys(kwargs)) {
1556 : 0 : PyErr_SetString(PyExc_TypeError,
1557 : : "keywords must be strings");
1558 : 0 : return 0;
1559 : : }
1560 : 124 : return 1;
1561 : : }
1562 : :
1563 : : #define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
1564 : :
1565 : : static int
1566 : 130233 : vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
1567 : : char **kwlist, va_list *p_va, int flags)
1568 : : {
1569 : : char msgbuf[512];
1570 : : int levels[32];
1571 : : const char *fname, *msg, *custom_msg;
1572 : 130233 : int min = INT_MAX;
1573 : 130233 : int max = INT_MAX;
1574 : : int i, pos, len;
1575 : 130233 : int skip = 0;
1576 : : Py_ssize_t nargs, nkwargs;
1577 : : PyObject *current_arg;
1578 : : freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
1579 : : freelist_t freelist;
1580 : :
1581 : 130233 : freelist.entries = static_entries;
1582 : 130233 : freelist.first_available = 0;
1583 : 130233 : freelist.entries_malloced = 0;
1584 : :
1585 : : assert(args != NULL && PyTuple_Check(args));
1586 : : assert(kwargs == NULL || PyDict_Check(kwargs));
1587 : : assert(format != NULL);
1588 : : assert(kwlist != NULL);
1589 : : assert(p_va != NULL);
1590 : :
1591 : : /* grab the function name or custom error msg first (mutually exclusive) */
1592 : 130233 : fname = strchr(format, ':');
1593 [ + + ]: 130233 : if (fname) {
1594 : 130049 : fname++;
1595 : 130049 : custom_msg = NULL;
1596 : : }
1597 : : else {
1598 : 184 : custom_msg = strchr(format,';');
1599 [ - + ]: 184 : if (custom_msg)
1600 : 0 : custom_msg++;
1601 : : }
1602 : :
1603 : : /* scan kwlist and count the number of positional-only parameters */
1604 [ + - - + ]: 130233 : for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) {
1605 : : }
1606 : : /* scan kwlist and get greatest possible nbr of args */
1607 [ + + ]: 391040 : for (len = pos; kwlist[len]; len++) {
1608 [ - + ]: 260807 : if (!*kwlist[len]) {
1609 : 0 : PyErr_SetString(PyExc_SystemError,
1610 : : "Empty keyword parameter name");
1611 : 0 : return cleanreturn(0, &freelist);
1612 : : }
1613 : : }
1614 : :
1615 [ + + ]: 130233 : if (len > STATIC_FREELIST_ENTRIES) {
1616 [ + - ]: 30 : freelist.entries = PyMem_NEW(freelistentry_t, len);
1617 [ - + ]: 30 : if (freelist.entries == NULL) {
1618 : 0 : PyErr_NoMemory();
1619 : 0 : return 0;
1620 : : }
1621 : 30 : freelist.entries_malloced = 1;
1622 : : }
1623 : :
1624 : 130233 : nargs = PyTuple_GET_SIZE(args);
1625 [ + + ]: 130233 : nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs);
1626 [ - + ]: 130233 : if (nargs + nkwargs > len) {
1627 : : /* Adding "keyword" (when nargs == 0) prevents producing wrong error
1628 : : messages in some special cases (see bpo-31229). */
1629 [ # # # # : 0 : PyErr_Format(PyExc_TypeError,
# # # # ]
1630 : : "%.200s%s takes at most %d %sargument%s (%zd given)",
1631 : : (fname == NULL) ? "function" : fname,
1632 : : (fname == NULL) ? "" : "()",
1633 : : len,
1634 : : (nargs == 0) ? "keyword " : "",
1635 : : (len == 1) ? "" : "s",
1636 : : nargs + nkwargs);
1637 : 0 : return cleanreturn(0, &freelist);
1638 : : }
1639 : :
1640 : : /* convert tuple args and keyword args in same loop, using kwlist to drive process */
1641 [ + + ]: 131523 : for (i = 0; i < len; i++) {
1642 [ + + ]: 131015 : if (*format == '|') {
1643 [ - + ]: 130118 : if (min != INT_MAX) {
1644 : 0 : PyErr_SetString(PyExc_SystemError,
1645 : : "Invalid format string (| specified twice)");
1646 : 0 : return cleanreturn(0, &freelist);
1647 : : }
1648 : :
1649 : 130118 : min = i;
1650 : 130118 : format++;
1651 : :
1652 [ - + ]: 130118 : if (max != INT_MAX) {
1653 : 0 : PyErr_SetString(PyExc_SystemError,
1654 : : "Invalid format string ($ before |)");
1655 : 0 : return cleanreturn(0, &freelist);
1656 : : }
1657 : : }
1658 [ + + ]: 131015 : if (*format == '$') {
1659 [ - + ]: 126975 : if (max != INT_MAX) {
1660 : 0 : PyErr_SetString(PyExc_SystemError,
1661 : : "Invalid format string ($ specified twice)");
1662 : 0 : return cleanreturn(0, &freelist);
1663 : : }
1664 : :
1665 : 126975 : max = i;
1666 : 126975 : format++;
1667 : :
1668 [ - + ]: 126975 : if (max < pos) {
1669 : 0 : PyErr_SetString(PyExc_SystemError,
1670 : : "Empty parameter name after $");
1671 : 0 : return cleanreturn(0, &freelist);
1672 : : }
1673 [ - + ]: 126975 : if (skip) {
1674 : : /* Now we know the minimal and the maximal numbers of
1675 : : * positional arguments and can raise an exception with
1676 : : * informative message (see below). */
1677 : 0 : break;
1678 : : }
1679 [ - + ]: 126975 : if (max < nargs) {
1680 [ # # ]: 0 : if (max == 0) {
1681 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
1682 : : "%.200s%s takes no positional arguments",
1683 : : (fname == NULL) ? "function" : fname,
1684 : : (fname == NULL) ? "" : "()");
1685 : : }
1686 : : else {
1687 [ # # # # : 0 : PyErr_Format(PyExc_TypeError,
# # # # ]
1688 : : "%.200s%s takes %s %d positional argument%s"
1689 : : " (%zd given)",
1690 : : (fname == NULL) ? "function" : fname,
1691 : : (fname == NULL) ? "" : "()",
1692 : : (min != INT_MAX) ? "at most" : "exactly",
1693 : : max,
1694 : : max == 1 ? "" : "s",
1695 : : nargs);
1696 : : }
1697 : 0 : return cleanreturn(0, &freelist);
1698 : : }
1699 : : }
1700 [ + - + - : 131015 : if (IS_END_OF_FORMAT(*format)) {
- + ]
1701 : 0 : PyErr_Format(PyExc_SystemError,
1702 : : "More keyword list entries (%d) than "
1703 : : "format specifiers (%d)", len, i);
1704 : 0 : return cleanreturn(0, &freelist);
1705 : : }
1706 [ + - ]: 131015 : if (!skip) {
1707 [ + + ]: 131015 : if (i < nargs) {
1708 : 352 : current_arg = PyTuple_GET_ITEM(args, i);
1709 : : }
1710 [ + + + - ]: 130663 : else if (nkwargs && i >= pos) {
1711 : 938 : current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
1712 [ + + ]: 938 : if (current_arg) {
1713 : 714 : --nkwargs;
1714 : : }
1715 [ - + ]: 224 : else if (PyErr_Occurred()) {
1716 : 0 : return cleanreturn(0, &freelist);
1717 : : }
1718 : : }
1719 : : else {
1720 : 129725 : current_arg = NULL;
1721 : : }
1722 : :
1723 [ + + ]: 131015 : if (current_arg) {
1724 : 1066 : msg = convertitem(current_arg, &format, p_va, flags,
1725 : : levels, msgbuf, sizeof(msgbuf), &freelist);
1726 [ - + ]: 1066 : if (msg) {
1727 : 0 : seterror(i+1, msg, levels, fname, custom_msg);
1728 : 0 : return cleanreturn(0, &freelist);
1729 : : }
1730 : 1066 : continue;
1731 : : }
1732 : :
1733 [ - + ]: 129949 : if (i < min) {
1734 [ # # ]: 0 : if (i < pos) {
1735 : : assert (min == INT_MAX);
1736 : : assert (max == INT_MAX);
1737 : 0 : skip = 1;
1738 : : /* At that moment we still don't know the minimal and
1739 : : * the maximal numbers of positional arguments. Raising
1740 : : * an exception is deferred until we encounter | and $
1741 : : * or the end of the format. */
1742 : : }
1743 : : else {
1744 [ # # ]: 0 : PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
1745 : : "argument '%s' (pos %d)",
1746 : : (fname == NULL) ? "function" : fname,
1747 : : (fname == NULL) ? "" : "()",
1748 [ # # ]: 0 : kwlist[i], i+1);
1749 : 0 : return cleanreturn(0, &freelist);
1750 : : }
1751 : : }
1752 : : /* current code reports success when all required args
1753 : : * fulfilled and no keyword args left, with no further
1754 : : * validation. XXX Maybe skip this in debug build ?
1755 : : */
1756 [ + + + - ]: 129949 : if (!nkwargs && !skip) {
1757 : 129725 : return cleanreturn(1, &freelist);
1758 : : }
1759 : : }
1760 : :
1761 : : /* We are into optional args, skip through to any remaining
1762 : : * keyword args */
1763 : 224 : msg = skipitem(&format, p_va, flags);
1764 [ - + ]: 224 : if (msg) {
1765 : 0 : PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
1766 : : format);
1767 : 0 : return cleanreturn(0, &freelist);
1768 : : }
1769 : : }
1770 : :
1771 [ - + ]: 508 : if (skip) {
1772 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
1773 : : "%.200s%s takes %s %d positional argument%s"
1774 : : " (%zd given)",
1775 : : (fname == NULL) ? "function" : fname,
1776 : : (fname == NULL) ? "" : "()",
1777 [ # # ]: 0 : (Py_MIN(pos, min) < i) ? "at least" : "exactly",
1778 : : Py_MIN(pos, min),
1779 [ # # ]: 0 : Py_MIN(pos, min) == 1 ? "" : "s",
1780 : : nargs);
1781 : 0 : return cleanreturn(0, &freelist);
1782 : : }
1783 : :
1784 [ + - + - : 508 : if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
- + - - -
- ]
1785 : 0 : PyErr_Format(PyExc_SystemError,
1786 : : "more argument specifiers than keyword list entries "
1787 : : "(remaining format:'%s')", format);
1788 : 0 : return cleanreturn(0, &freelist);
1789 : : }
1790 : :
1791 [ - + ]: 508 : if (nkwargs > 0) {
1792 : : PyObject *key;
1793 : : Py_ssize_t j;
1794 : : /* make sure there are no arguments given by name and position */
1795 [ # # ]: 0 : for (i = pos; i < nargs; i++) {
1796 : 0 : current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
1797 [ # # ]: 0 : if (current_arg) {
1798 : : /* arg present in tuple and in dict */
1799 [ # # ]: 0 : PyErr_Format(PyExc_TypeError,
1800 : : "argument for %.200s%s given by name ('%s') "
1801 : : "and position (%d)",
1802 : : (fname == NULL) ? "function" : fname,
1803 : : (fname == NULL) ? "" : "()",
1804 [ # # ]: 0 : kwlist[i], i+1);
1805 : 0 : return cleanreturn(0, &freelist);
1806 : : }
1807 [ # # ]: 0 : else if (PyErr_Occurred()) {
1808 : 0 : return cleanreturn(0, &freelist);
1809 : : }
1810 : : }
1811 : : /* make sure there are no extraneous keyword arguments */
1812 : 0 : j = 0;
1813 [ # # ]: 0 : while (PyDict_Next(kwargs, &j, &key, NULL)) {
1814 : 0 : int match = 0;
1815 [ # # ]: 0 : if (!PyUnicode_Check(key)) {
1816 : 0 : PyErr_SetString(PyExc_TypeError,
1817 : : "keywords must be strings");
1818 : 0 : return cleanreturn(0, &freelist);
1819 : : }
1820 [ # # ]: 0 : for (i = pos; i < len; i++) {
1821 [ # # ]: 0 : if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) {
1822 : 0 : match = 1;
1823 : 0 : break;
1824 : : }
1825 : : }
1826 [ # # ]: 0 : if (!match) {
1827 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
1828 : : "'%U' is an invalid keyword "
1829 : : "argument for %.200s%s",
1830 : : key,
1831 : : (fname == NULL) ? "this function" : fname,
1832 : : (fname == NULL) ? "" : "()");
1833 : 0 : return cleanreturn(0, &freelist);
1834 : : }
1835 : : }
1836 : : /* Something wrong happened. There are extraneous keyword arguments,
1837 : : * but we don't know what. And we don't bother. */
1838 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
1839 : : "invalid keyword argument for %.200s%s",
1840 : : (fname == NULL) ? "this function" : fname,
1841 : : (fname == NULL) ? "" : "()");
1842 : 0 : return cleanreturn(0, &freelist);
1843 : : }
1844 : :
1845 : 508 : return cleanreturn(1, &freelist);
1846 : : }
1847 : :
1848 : :
1849 : : static int
1850 : 88 : scan_keywords(const char * const *keywords, int *ptotal, int *pposonly)
1851 : : {
1852 : : /* scan keywords and count the number of positional-only parameters */
1853 : : int i;
1854 [ + - + + ]: 89 : for (i = 0; keywords[i] && !*keywords[i]; i++) {
1855 : : }
1856 : 88 : *pposonly = i;
1857 : :
1858 : : /* scan keywords and get greatest possible nbr of args */
1859 [ + + ]: 517 : for (; keywords[i]; i++) {
1860 [ - + ]: 429 : if (!*keywords[i]) {
1861 : 0 : PyErr_SetString(PyExc_SystemError,
1862 : : "Empty keyword parameter name");
1863 : 0 : return -1;
1864 : : }
1865 : : }
1866 : 88 : *ptotal = i;
1867 : 88 : return 0;
1868 : : }
1869 : :
1870 : : static int
1871 : 0 : parse_format(const char *format, int total, int npos,
1872 : : const char **pfname, const char **pcustommsg,
1873 : : int *pmin, int *pmax)
1874 : : {
1875 : : /* grab the function name or custom error msg first (mutually exclusive) */
1876 : : const char *custommsg;
1877 : 0 : const char *fname = strchr(format, ':');
1878 [ # # ]: 0 : if (fname) {
1879 : 0 : fname++;
1880 : 0 : custommsg = NULL;
1881 : : }
1882 : : else {
1883 : 0 : custommsg = strchr(format,';');
1884 [ # # ]: 0 : if (custommsg) {
1885 : 0 : custommsg++;
1886 : : }
1887 : : }
1888 : :
1889 : 0 : int min = INT_MAX;
1890 : 0 : int max = INT_MAX;
1891 [ # # ]: 0 : for (int i = 0; i < total; i++) {
1892 [ # # ]: 0 : if (*format == '|') {
1893 [ # # ]: 0 : if (min != INT_MAX) {
1894 : 0 : PyErr_SetString(PyExc_SystemError,
1895 : : "Invalid format string (| specified twice)");
1896 : 0 : return -1;
1897 : : }
1898 [ # # ]: 0 : if (max != INT_MAX) {
1899 : 0 : PyErr_SetString(PyExc_SystemError,
1900 : : "Invalid format string ($ before |)");
1901 : 0 : return -1;
1902 : : }
1903 : 0 : min = i;
1904 : 0 : format++;
1905 : : }
1906 [ # # ]: 0 : if (*format == '$') {
1907 [ # # ]: 0 : if (max != INT_MAX) {
1908 : 0 : PyErr_SetString(PyExc_SystemError,
1909 : : "Invalid format string ($ specified twice)");
1910 : 0 : return -1;
1911 : : }
1912 [ # # ]: 0 : if (i < npos) {
1913 : 0 : PyErr_SetString(PyExc_SystemError,
1914 : : "Empty parameter name after $");
1915 : 0 : return -1;
1916 : : }
1917 : 0 : max = i;
1918 : 0 : format++;
1919 : : }
1920 [ # # # # : 0 : if (IS_END_OF_FORMAT(*format)) {
# # ]
1921 : 0 : PyErr_Format(PyExc_SystemError,
1922 : : "More keyword list entries (%d) than "
1923 : : "format specifiers (%d)", total, i);
1924 : 0 : return -1;
1925 : : }
1926 : :
1927 : 0 : const char *msg = skipitem(&format, NULL, 0);
1928 [ # # ]: 0 : if (msg) {
1929 : 0 : PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
1930 : : format);
1931 : 0 : return -1;
1932 : : }
1933 : : }
1934 : 0 : min = Py_MIN(min, total);
1935 : 0 : max = Py_MIN(max, total);
1936 : :
1937 [ # # # # : 0 : if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
# # # # #
# ]
1938 : 0 : PyErr_Format(PyExc_SystemError,
1939 : : "more argument specifiers than keyword list entries "
1940 : : "(remaining format:'%s')", format);
1941 : 0 : return -1;
1942 : : }
1943 : :
1944 : 0 : *pfname = fname;
1945 : 0 : *pcustommsg = custommsg;
1946 : 0 : *pmin = min;
1947 : 0 : *pmax = max;
1948 : 0 : return 0;
1949 : : }
1950 : :
1951 : : static PyObject *
1952 : 15 : new_kwtuple(const char * const *keywords, int total, int pos)
1953 : : {
1954 : 15 : int nkw = total - pos;
1955 : 15 : PyObject *kwtuple = PyTuple_New(nkw);
1956 [ - + ]: 15 : if (kwtuple == NULL) {
1957 : 0 : return NULL;
1958 : : }
1959 : 15 : keywords += pos;
1960 [ + + ]: 46 : for (int i = 0; i < nkw; i++) {
1961 : 31 : PyObject *str = PyUnicode_FromString(keywords[i]);
1962 [ - + ]: 31 : if (str == NULL) {
1963 : 0 : Py_DECREF(kwtuple);
1964 : 0 : return NULL;
1965 : : }
1966 : 31 : PyUnicode_InternInPlace(&str);
1967 : 31 : PyTuple_SET_ITEM(kwtuple, i, str);
1968 : : }
1969 : 15 : return kwtuple;
1970 : : }
1971 : :
1972 : : static int
1973 : 88 : _parser_init(struct _PyArg_Parser *parser)
1974 : : {
1975 : 88 : const char * const *keywords = parser->keywords;
1976 : : assert(keywords != NULL);
1977 : : assert(parser->pos == 0 &&
1978 : : (parser->format == NULL || parser->fname == NULL) &&
1979 : : parser->custom_msg == NULL &&
1980 : : parser->min == 0 &&
1981 : : parser->max == 0);
1982 : :
1983 : : int len, pos;
1984 [ - + ]: 88 : if (scan_keywords(keywords, &len, &pos) < 0) {
1985 : 0 : return 0;
1986 : : }
1987 : :
1988 : 88 : const char *fname, *custommsg = NULL;
1989 : 88 : int min = 0, max = 0;
1990 [ - + ]: 88 : if (parser->format) {
1991 : : assert(parser->fname == NULL);
1992 [ # # ]: 0 : if (parse_format(parser->format, len, pos,
1993 : : &fname, &custommsg, &min, &max) < 0) {
1994 : 0 : return 0;
1995 : : }
1996 : : }
1997 : : else {
1998 : : assert(parser->fname != NULL);
1999 : 88 : fname = parser->fname;
2000 : : }
2001 : :
2002 : : int owned;
2003 : 88 : PyObject *kwtuple = parser->kwtuple;
2004 [ + + ]: 88 : if (kwtuple == NULL) {
2005 : 15 : kwtuple = new_kwtuple(keywords, len, pos);
2006 [ - + ]: 15 : if (kwtuple == NULL) {
2007 : 0 : return 0;
2008 : : }
2009 : 15 : owned = 1;
2010 : : }
2011 : : else {
2012 : 73 : owned = 0;
2013 : : }
2014 : :
2015 : 88 : parser->pos = pos;
2016 : 88 : parser->fname = fname;
2017 : 88 : parser->custom_msg = custommsg;
2018 : 88 : parser->min = min;
2019 : 88 : parser->max = max;
2020 : 88 : parser->kwtuple = kwtuple;
2021 [ + + ]: 88 : parser->initialized = owned ? 1 : -1;
2022 : :
2023 : : assert(parser->next == NULL);
2024 : 88 : parser->next = _PyRuntime.getargs.static_parsers;
2025 : 88 : _PyRuntime.getargs.static_parsers = parser;
2026 : 88 : return 1;
2027 : : }
2028 : :
2029 : : static int
2030 : 1148 : parser_init(struct _PyArg_Parser *parser)
2031 : : {
2032 : : // volatile as it can be modified by other threads
2033 : : // and should not be optimized or reordered by compiler
2034 [ + + ]: 1148 : if (*((volatile int *)&parser->initialized)) {
2035 : : assert(parser->kwtuple != NULL);
2036 : 1060 : return 1;
2037 : : }
2038 : 88 : PyThread_acquire_lock(_PyRuntime.getargs.mutex, WAIT_LOCK);
2039 : : // Check again if another thread initialized the parser
2040 : : // while we were waiting for the lock.
2041 [ - + ]: 88 : if (*((volatile int *)&parser->initialized)) {
2042 : : assert(parser->kwtuple != NULL);
2043 : 0 : PyThread_release_lock(_PyRuntime.getargs.mutex);
2044 : 0 : return 1;
2045 : : }
2046 : 88 : int ret = _parser_init(parser);
2047 : 88 : PyThread_release_lock(_PyRuntime.getargs.mutex);
2048 : 88 : return ret;
2049 : : }
2050 : :
2051 : : static void
2052 : 88 : parser_clear(struct _PyArg_Parser *parser)
2053 : : {
2054 [ + + ]: 88 : if (parser->initialized == 1) {
2055 [ + - ]: 15 : Py_CLEAR(parser->kwtuple);
2056 : : }
2057 : 88 : }
2058 : :
2059 : : static PyObject*
2060 : 3127 : find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key)
2061 : : {
2062 : : Py_ssize_t i, nkwargs;
2063 : :
2064 : 3127 : nkwargs = PyTuple_GET_SIZE(kwnames);
2065 [ + + ]: 5443 : for (i = 0; i < nkwargs; i++) {
2066 : 3726 : PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
2067 : :
2068 : : /* kwname == key will normally find a match in since keyword keys
2069 : : should be interned strings; if not retry below in a new loop. */
2070 [ + + ]: 3726 : if (kwname == key) {
2071 : 1410 : return kwstack[i];
2072 : : }
2073 : : }
2074 : :
2075 [ + + ]: 3752 : for (i = 0; i < nkwargs; i++) {
2076 : 2035 : PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
2077 : : assert(PyUnicode_Check(kwname));
2078 [ - + ]: 2035 : if (_PyUnicode_EQ(kwname, key)) {
2079 : 0 : return kwstack[i];
2080 : : }
2081 : : }
2082 : 1717 : return NULL;
2083 : : }
2084 : :
2085 : : static int
2086 : 0 : vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
2087 : : PyObject *kwargs, PyObject *kwnames,
2088 : : struct _PyArg_Parser *parser,
2089 : : va_list *p_va, int flags)
2090 : : {
2091 : : PyObject *kwtuple;
2092 : : char msgbuf[512];
2093 : : int levels[32];
2094 : : const char *format;
2095 : : const char *msg;
2096 : : PyObject *keyword;
2097 : : int i, pos, len;
2098 : : Py_ssize_t nkwargs;
2099 : : PyObject *current_arg;
2100 : : freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
2101 : : freelist_t freelist;
2102 : 0 : PyObject *const *kwstack = NULL;
2103 : :
2104 : 0 : freelist.entries = static_entries;
2105 : 0 : freelist.first_available = 0;
2106 : 0 : freelist.entries_malloced = 0;
2107 : :
2108 : : assert(kwargs == NULL || PyDict_Check(kwargs));
2109 : : assert(kwargs == NULL || kwnames == NULL);
2110 : : assert(p_va != NULL);
2111 : :
2112 [ # # ]: 0 : if (parser == NULL) {
2113 : 0 : PyErr_BadInternalCall();
2114 : 0 : return 0;
2115 : : }
2116 : :
2117 [ # # # # ]: 0 : if (kwnames != NULL && !PyTuple_Check(kwnames)) {
2118 : 0 : PyErr_BadInternalCall();
2119 : 0 : return 0;
2120 : : }
2121 : :
2122 [ # # ]: 0 : if (!parser_init(parser)) {
2123 : 0 : return 0;
2124 : : }
2125 : :
2126 : 0 : kwtuple = parser->kwtuple;
2127 : 0 : pos = parser->pos;
2128 : 0 : len = pos + (int)PyTuple_GET_SIZE(kwtuple);
2129 : :
2130 [ # # ]: 0 : if (len > STATIC_FREELIST_ENTRIES) {
2131 [ # # ]: 0 : freelist.entries = PyMem_NEW(freelistentry_t, len);
2132 [ # # ]: 0 : if (freelist.entries == NULL) {
2133 : 0 : PyErr_NoMemory();
2134 : 0 : return 0;
2135 : : }
2136 : 0 : freelist.entries_malloced = 1;
2137 : : }
2138 : :
2139 [ # # ]: 0 : if (kwargs != NULL) {
2140 : 0 : nkwargs = PyDict_GET_SIZE(kwargs);
2141 : : }
2142 [ # # ]: 0 : else if (kwnames != NULL) {
2143 : 0 : nkwargs = PyTuple_GET_SIZE(kwnames);
2144 : 0 : kwstack = args + nargs;
2145 : : }
2146 : : else {
2147 : 0 : nkwargs = 0;
2148 : : }
2149 [ # # ]: 0 : if (nargs + nkwargs > len) {
2150 : : /* Adding "keyword" (when nargs == 0) prevents producing wrong error
2151 : : messages in some special cases (see bpo-31229). */
2152 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
2153 : : "%.200s%s takes at most %d %sargument%s (%zd given)",
2154 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2155 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2156 : : len,
2157 : : (nargs == 0) ? "keyword " : "",
2158 : : (len == 1) ? "" : "s",
2159 : : nargs + nkwargs);
2160 : 0 : return cleanreturn(0, &freelist);
2161 : : }
2162 [ # # ]: 0 : if (parser->max < nargs) {
2163 [ # # ]: 0 : if (parser->max == 0) {
2164 : 0 : PyErr_Format(PyExc_TypeError,
2165 : : "%.200s%s takes no positional arguments",
2166 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2167 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()");
2168 : : }
2169 : : else {
2170 : 0 : PyErr_Format(PyExc_TypeError,
2171 : : "%.200s%s takes %s %d positional argument%s (%zd given)",
2172 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2173 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2174 [ # # ]: 0 : (parser->min < parser->max) ? "at most" : "exactly",
2175 : : parser->max,
2176 [ # # ]: 0 : parser->max == 1 ? "" : "s",
2177 : : nargs);
2178 : : }
2179 : 0 : return cleanreturn(0, &freelist);
2180 : : }
2181 : :
2182 : 0 : format = parser->format;
2183 : : assert(format != NULL || len == 0);
2184 : : /* convert tuple args and keyword args in same loop, using kwtuple to drive process */
2185 [ # # ]: 0 : for (i = 0; i < len; i++) {
2186 [ # # ]: 0 : if (*format == '|') {
2187 : 0 : format++;
2188 : : }
2189 [ # # ]: 0 : if (*format == '$') {
2190 : 0 : format++;
2191 : : }
2192 : : assert(!IS_END_OF_FORMAT(*format));
2193 : :
2194 [ # # ]: 0 : if (i < nargs) {
2195 : 0 : current_arg = args[i];
2196 : : }
2197 [ # # # # ]: 0 : else if (nkwargs && i >= pos) {
2198 : 0 : keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
2199 [ # # ]: 0 : if (kwargs != NULL) {
2200 : 0 : current_arg = PyDict_GetItemWithError(kwargs, keyword);
2201 [ # # # # ]: 0 : if (!current_arg && PyErr_Occurred()) {
2202 : 0 : return cleanreturn(0, &freelist);
2203 : : }
2204 : : }
2205 : : else {
2206 : 0 : current_arg = find_keyword(kwnames, kwstack, keyword);
2207 : : }
2208 [ # # ]: 0 : if (current_arg) {
2209 : 0 : --nkwargs;
2210 : : }
2211 : : }
2212 : : else {
2213 : 0 : current_arg = NULL;
2214 : : }
2215 : :
2216 [ # # ]: 0 : if (current_arg) {
2217 : 0 : msg = convertitem(current_arg, &format, p_va, flags,
2218 : : levels, msgbuf, sizeof(msgbuf), &freelist);
2219 [ # # ]: 0 : if (msg) {
2220 : 0 : seterror(i+1, msg, levels, parser->fname, parser->custom_msg);
2221 : 0 : return cleanreturn(0, &freelist);
2222 : : }
2223 : 0 : continue;
2224 : : }
2225 : :
2226 [ # # ]: 0 : if (i < parser->min) {
2227 : : /* Less arguments than required */
2228 [ # # ]: 0 : if (i < pos) {
2229 : 0 : Py_ssize_t min = Py_MIN(pos, parser->min);
2230 [ # # ]: 0 : PyErr_Format(PyExc_TypeError,
2231 : : "%.200s%s takes %s %d positional argument%s"
2232 : : " (%zd given)",
2233 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2234 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2235 [ # # ]: 0 : min < parser->max ? "at least" : "exactly",
2236 : : min,
2237 : : min == 1 ? "" : "s",
2238 : : nargs);
2239 : : }
2240 : : else {
2241 : 0 : keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
2242 : 0 : PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
2243 : : "argument '%U' (pos %d)",
2244 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2245 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2246 : : keyword, i+1);
2247 : : }
2248 : 0 : return cleanreturn(0, &freelist);
2249 : : }
2250 : : /* current code reports success when all required args
2251 : : * fulfilled and no keyword args left, with no further
2252 : : * validation. XXX Maybe skip this in debug build ?
2253 : : */
2254 [ # # ]: 0 : if (!nkwargs) {
2255 : 0 : return cleanreturn(1, &freelist);
2256 : : }
2257 : :
2258 : : /* We are into optional args, skip through to any remaining
2259 : : * keyword args */
2260 : 0 : msg = skipitem(&format, p_va, flags);
2261 : : assert(msg == NULL);
2262 : : }
2263 : :
2264 : : assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$'));
2265 : :
2266 [ # # ]: 0 : if (nkwargs > 0) {
2267 : : /* make sure there are no arguments given by name and position */
2268 [ # # ]: 0 : for (i = pos; i < nargs; i++) {
2269 : 0 : keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
2270 [ # # ]: 0 : if (kwargs != NULL) {
2271 : 0 : current_arg = PyDict_GetItemWithError(kwargs, keyword);
2272 [ # # # # ]: 0 : if (!current_arg && PyErr_Occurred()) {
2273 : 0 : return cleanreturn(0, &freelist);
2274 : : }
2275 : : }
2276 : : else {
2277 : 0 : current_arg = find_keyword(kwnames, kwstack, keyword);
2278 : : }
2279 [ # # ]: 0 : if (current_arg) {
2280 : : /* arg present in tuple and in dict */
2281 : 0 : PyErr_Format(PyExc_TypeError,
2282 : : "argument for %.200s%s given by name ('%U') "
2283 : : "and position (%d)",
2284 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2285 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2286 : : keyword, i+1);
2287 : 0 : return cleanreturn(0, &freelist);
2288 : : }
2289 : : }
2290 : :
2291 : 0 : error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname);
2292 : 0 : return cleanreturn(0, &freelist);
2293 : : }
2294 : :
2295 : 0 : return cleanreturn(1, &freelist);
2296 : : }
2297 : :
2298 : : static int
2299 : 0 : vgetargskeywordsfast(PyObject *args, PyObject *keywords,
2300 : : struct _PyArg_Parser *parser, va_list *p_va, int flags)
2301 : : {
2302 : : PyObject **stack;
2303 : : Py_ssize_t nargs;
2304 : :
2305 [ # # ]: 0 : if (args == NULL
2306 [ # # ]: 0 : || !PyTuple_Check(args)
2307 [ # # # # ]: 0 : || (keywords != NULL && !PyDict_Check(keywords)))
2308 : : {
2309 : 0 : PyErr_BadInternalCall();
2310 : 0 : return 0;
2311 : : }
2312 : :
2313 : 0 : stack = _PyTuple_ITEMS(args);
2314 : 0 : nargs = PyTuple_GET_SIZE(args);
2315 : 0 : return vgetargskeywordsfast_impl(stack, nargs, keywords, NULL,
2316 : : parser, p_va, flags);
2317 : : }
2318 : :
2319 : :
2320 : : #undef _PyArg_UnpackKeywords
2321 : :
2322 : : PyObject * const *
2323 : 1100 : _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs,
2324 : : PyObject *kwargs, PyObject *kwnames,
2325 : : struct _PyArg_Parser *parser,
2326 : : int minpos, int maxpos, int minkw,
2327 : : PyObject **buf)
2328 : : {
2329 : : PyObject *kwtuple;
2330 : : PyObject *keyword;
2331 : : int i, posonly, minposonly, maxargs;
2332 [ - + ]: 1100 : int reqlimit = minkw ? maxpos + minkw : minpos;
2333 : : Py_ssize_t nkwargs;
2334 : : PyObject *current_arg;
2335 : 1100 : PyObject * const *kwstack = NULL;
2336 : :
2337 : : assert(kwargs == NULL || PyDict_Check(kwargs));
2338 : : assert(kwargs == NULL || kwnames == NULL);
2339 : :
2340 [ - + ]: 1100 : if (parser == NULL) {
2341 : 0 : PyErr_BadInternalCall();
2342 : 0 : return NULL;
2343 : : }
2344 : :
2345 [ + + - + ]: 1100 : if (kwnames != NULL && !PyTuple_Check(kwnames)) {
2346 : 0 : PyErr_BadInternalCall();
2347 : 0 : return NULL;
2348 : : }
2349 : :
2350 [ - + - - ]: 1100 : if (args == NULL && nargs == 0) {
2351 : 0 : args = buf;
2352 : : }
2353 : :
2354 [ - + ]: 1100 : if (!parser_init(parser)) {
2355 : 0 : return NULL;
2356 : : }
2357 : :
2358 : 1100 : kwtuple = parser->kwtuple;
2359 : 1100 : posonly = parser->pos;
2360 : 1100 : minposonly = Py_MIN(posonly, minpos);
2361 : 1100 : maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
2362 : :
2363 [ + + ]: 1100 : if (kwargs != NULL) {
2364 : 3 : nkwargs = PyDict_GET_SIZE(kwargs);
2365 : : }
2366 [ + + ]: 1097 : else if (kwnames != NULL) {
2367 : 1095 : nkwargs = PyTuple_GET_SIZE(kwnames);
2368 : 1095 : kwstack = args + nargs;
2369 : : }
2370 : : else {
2371 : 2 : nkwargs = 0;
2372 : : }
2373 [ + + + - : 1100 : if (nkwargs == 0 && minkw == 0 && minpos <= nargs && nargs <= maxpos) {
+ + - + ]
2374 : : /* Fast path. */
2375 : 0 : return args;
2376 : : }
2377 [ - + ]: 1100 : if (nargs + nkwargs > maxargs) {
2378 : : /* Adding "keyword" (when nargs == 0) prevents producing wrong error
2379 : : messages in some special cases (see bpo-31229). */
2380 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
2381 : : "%.200s%s takes at most %d %sargument%s (%zd given)",
2382 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2383 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2384 : : maxargs,
2385 : : (nargs == 0) ? "keyword " : "",
2386 : : (maxargs == 1) ? "" : "s",
2387 : : nargs + nkwargs);
2388 : 0 : return NULL;
2389 : : }
2390 [ + + ]: 1100 : if (nargs > maxpos) {
2391 [ - + ]: 1 : if (maxpos == 0) {
2392 : 0 : PyErr_Format(PyExc_TypeError,
2393 : : "%.200s%s takes no positional arguments",
2394 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2395 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()");
2396 : : }
2397 : : else {
2398 [ + - - + ]: 3 : PyErr_Format(PyExc_TypeError,
2399 : : "%.200s%s takes %s %d positional argument%s (%zd given)",
2400 [ + - ]: 1 : (parser->fname == NULL) ? "function" : parser->fname,
2401 [ - + ]: 1 : (parser->fname == NULL) ? "" : "()",
2402 : : (minpos < maxpos) ? "at most" : "exactly",
2403 : : maxpos,
2404 : : (maxpos == 1) ? "" : "s",
2405 : : nargs);
2406 : : }
2407 : 1 : return NULL;
2408 : : }
2409 [ + + ]: 1099 : if (nargs < minposonly) {
2410 [ + - - + ]: 3 : PyErr_Format(PyExc_TypeError,
2411 : : "%.200s%s takes %s %d positional argument%s"
2412 : : " (%zd given)",
2413 [ + - ]: 1 : (parser->fname == NULL) ? "function" : parser->fname,
2414 [ - + ]: 1 : (parser->fname == NULL) ? "" : "()",
2415 : : minposonly < maxpos ? "at least" : "exactly",
2416 : : minposonly,
2417 : : minposonly == 1 ? "" : "s",
2418 : : nargs);
2419 : 1 : return NULL;
2420 : : }
2421 : :
2422 : : /* copy tuple args */
2423 [ + + ]: 2677 : for (i = 0; i < nargs; i++) {
2424 : 1579 : buf[i] = args[i];
2425 : : }
2426 : :
2427 : : /* copy keyword args using kwtuple to drive process */
2428 [ + + ]: 4118 : for (i = Py_MAX((int)nargs, posonly); i < maxargs; i++) {
2429 [ + + ]: 3929 : if (nkwargs) {
2430 : 3020 : keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
2431 [ + + ]: 3020 : if (kwargs != NULL) {
2432 : 9 : current_arg = PyDict_GetItemWithError(kwargs, keyword);
2433 [ + + - + ]: 9 : if (!current_arg && PyErr_Occurred()) {
2434 : 0 : return NULL;
2435 : : }
2436 : : }
2437 : : else {
2438 : 3011 : current_arg = find_keyword(kwnames, kwstack, keyword);
2439 : : }
2440 : : }
2441 [ + - ]: 909 : else if (i >= reqlimit) {
2442 : 909 : break;
2443 : : }
2444 : : else {
2445 : 0 : current_arg = NULL;
2446 : : }
2447 : :
2448 : 3020 : buf[i] = current_arg;
2449 : :
2450 [ + + ]: 3020 : if (current_arg) {
2451 : 1339 : --nkwargs;
2452 : : }
2453 [ + - + + : 1681 : else if (i < minpos || (maxpos <= i && i < reqlimit)) {
- + ]
2454 : : /* Less arguments than required */
2455 : 0 : keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
2456 : 0 : PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
2457 : : "argument '%U' (pos %d)",
2458 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2459 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2460 : : keyword, i+1);
2461 : 0 : return NULL;
2462 : : }
2463 : : }
2464 : :
2465 [ - + ]: 1098 : if (nkwargs > 0) {
2466 : : /* make sure there are no arguments given by name and position */
2467 [ # # ]: 0 : for (i = posonly; i < nargs; i++) {
2468 : 0 : keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
2469 [ # # ]: 0 : if (kwargs != NULL) {
2470 : 0 : current_arg = PyDict_GetItemWithError(kwargs, keyword);
2471 [ # # # # ]: 0 : if (!current_arg && PyErr_Occurred()) {
2472 : 0 : return NULL;
2473 : : }
2474 : : }
2475 : : else {
2476 : 0 : current_arg = find_keyword(kwnames, kwstack, keyword);
2477 : : }
2478 [ # # ]: 0 : if (current_arg) {
2479 : : /* arg present in tuple and in dict */
2480 : 0 : PyErr_Format(PyExc_TypeError,
2481 : : "argument for %.200s%s given by name ('%U') "
2482 : : "and position (%d)",
2483 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2484 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2485 : : keyword, i+1);
2486 : 0 : return NULL;
2487 : : }
2488 : : }
2489 : :
2490 : 0 : error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname);
2491 : 0 : return NULL;
2492 : : }
2493 : :
2494 : 1098 : return buf;
2495 : : }
2496 : :
2497 : : PyObject * const *
2498 : 48 : _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs,
2499 : : PyObject *kwargs, PyObject *kwnames,
2500 : : struct _PyArg_Parser *parser,
2501 : : int minpos, int maxpos, int minkw,
2502 : : int vararg, PyObject **buf)
2503 : : {
2504 : : PyObject *kwtuple;
2505 : : PyObject *keyword;
2506 : 48 : Py_ssize_t varargssize = 0;
2507 : : int i, posonly, minposonly, maxargs;
2508 [ - + ]: 48 : int reqlimit = minkw ? maxpos + minkw : minpos;
2509 : : Py_ssize_t nkwargs;
2510 : : PyObject *current_arg;
2511 : 48 : PyObject * const *kwstack = NULL;
2512 : :
2513 : : assert(kwargs == NULL || PyDict_Check(kwargs));
2514 : : assert(kwargs == NULL || kwnames == NULL);
2515 : :
2516 [ - + ]: 48 : if (parser == NULL) {
2517 : 0 : PyErr_BadInternalCall();
2518 : 0 : return NULL;
2519 : : }
2520 : :
2521 [ + + - + ]: 48 : if (kwnames != NULL && !PyTuple_Check(kwnames)) {
2522 : 0 : PyErr_BadInternalCall();
2523 : 0 : return NULL;
2524 : : }
2525 : :
2526 [ - + - - ]: 48 : if (args == NULL && nargs == 0) {
2527 : 0 : args = buf;
2528 : : }
2529 : :
2530 [ - + ]: 48 : if (!parser_init(parser)) {
2531 : 0 : return NULL;
2532 : : }
2533 : :
2534 : 48 : kwtuple = parser->kwtuple;
2535 : 48 : posonly = parser->pos;
2536 : 48 : minposonly = Py_MIN(posonly, minpos);
2537 : 48 : maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
2538 [ - + ]: 48 : if (kwargs != NULL) {
2539 : 0 : nkwargs = PyDict_GET_SIZE(kwargs);
2540 : : }
2541 [ + + ]: 48 : else if (kwnames != NULL) {
2542 : 38 : nkwargs = PyTuple_GET_SIZE(kwnames);
2543 : 38 : kwstack = args + nargs;
2544 : : }
2545 : : else {
2546 : 10 : nkwargs = 0;
2547 : : }
2548 [ - + ]: 48 : if (nargs < minposonly) {
2549 [ # # # # ]: 0 : PyErr_Format(PyExc_TypeError,
2550 : : "%.200s%s takes %s %d positional argument%s"
2551 : : " (%zd given)",
2552 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2553 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2554 : : minposonly < maxpos ? "at least" : "exactly",
2555 : : minposonly,
2556 : : minposonly == 1 ? "" : "s",
2557 : : nargs);
2558 : 0 : return NULL;
2559 : : }
2560 : :
2561 : : /* create varargs tuple */
2562 : 48 : varargssize = nargs - maxpos;
2563 [ - + ]: 48 : if (varargssize < 0) {
2564 : 0 : varargssize = 0;
2565 : : }
2566 : 48 : buf[vararg] = PyTuple_New(varargssize);
2567 [ - + ]: 48 : if (!buf[vararg]) {
2568 : 0 : return NULL;
2569 : : }
2570 : :
2571 : : /* copy tuple args */
2572 [ + + ]: 94 : for (i = 0; i < nargs; i++) {
2573 [ + - ]: 46 : if (i >= vararg) {
2574 : 46 : PyTuple_SET_ITEM(buf[vararg], i - vararg, Py_NewRef(args[i]));
2575 : 46 : continue;
2576 : : }
2577 : : else {
2578 : 0 : buf[i] = args[i];
2579 : : }
2580 : : }
2581 : :
2582 : : /* copy keyword args using kwtuple to drive process */
2583 [ + + ]: 240 : for (i = Py_MAX((int)nargs, posonly) -
2584 : 240 : Py_SAFE_DOWNCAST(varargssize, Py_ssize_t, int); i < maxargs; i++) {
2585 [ + + ]: 192 : if (nkwargs) {
2586 : 116 : keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
2587 [ - + ]: 116 : if (kwargs != NULL) {
2588 : 0 : current_arg = PyDict_GetItemWithError(kwargs, keyword);
2589 [ # # # # ]: 0 : if (!current_arg && PyErr_Occurred()) {
2590 : 0 : goto exit;
2591 : : }
2592 : : }
2593 : : else {
2594 : 116 : current_arg = find_keyword(kwnames, kwstack, keyword);
2595 : : }
2596 : : }
2597 : : else {
2598 : 76 : current_arg = NULL;
2599 : : }
2600 : :
2601 : : /* If an arguments is passed in as a keyword argument,
2602 : : * it should be placed before `buf[vararg]`.
2603 : : *
2604 : : * For example:
2605 : : * def f(a, /, b, *args):
2606 : : * pass
2607 : : * f(1, b=2)
2608 : : *
2609 : : * This `buf` array should be: [1, 2, NULL].
2610 : : * In this case, nargs < vararg.
2611 : : *
2612 : : * Otherwise, we leave a place at `buf[vararg]` for vararg tuple
2613 : : * so the index is `i + 1`. */
2614 [ - + ]: 192 : if (nargs < vararg) {
2615 : 0 : buf[i] = current_arg;
2616 : : }
2617 : : else {
2618 : 192 : buf[i + 1] = current_arg;
2619 : : }
2620 : :
2621 [ + + ]: 192 : if (current_arg) {
2622 : 74 : --nkwargs;
2623 : : }
2624 [ + - + - : 118 : else if (i < minpos || (maxpos <= i && i < reqlimit)) {
- + ]
2625 : : /* Less arguments than required */
2626 : 0 : keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
2627 : 0 : PyErr_Format(PyExc_TypeError, "%.200s%s missing required "
2628 : : "argument '%U' (pos %d)",
2629 [ # # ]: 0 : (parser->fname == NULL) ? "function" : parser->fname,
2630 [ # # ]: 0 : (parser->fname == NULL) ? "" : "()",
2631 : : keyword, i+1);
2632 : 0 : goto exit;
2633 : : }
2634 : : }
2635 : :
2636 [ - + ]: 48 : if (nkwargs > 0) {
2637 : 0 : error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname);
2638 : 0 : goto exit;
2639 : : }
2640 : :
2641 : 48 : return buf;
2642 : :
2643 : 0 : exit:
2644 : 0 : Py_XDECREF(buf[vararg]);
2645 : 0 : return NULL;
2646 : : }
2647 : :
2648 : :
2649 : : static const char *
2650 : 224 : skipitem(const char **p_format, va_list *p_va, int flags)
2651 : : {
2652 : 224 : const char *format = *p_format;
2653 : 224 : char c = *format++;
2654 : :
2655 [ + - - + : 224 : switch (c) {
- - - ]
2656 : :
2657 : : /*
2658 : : * codes that take a single data pointer as an argument
2659 : : * (the type of the pointer is irrelevant)
2660 : : */
2661 : :
2662 : 3 : case 'b': /* byte -- very short int */
2663 : : case 'B': /* byte as bitfield */
2664 : : case 'h': /* short int */
2665 : : case 'H': /* short int as bitfield */
2666 : : case 'i': /* int */
2667 : : case 'I': /* int sized bitfield */
2668 : : case 'l': /* long int */
2669 : : case 'k': /* long int sized bitfield */
2670 : : case 'L': /* long long */
2671 : : case 'K': /* long long sized bitfield */
2672 : : case 'n': /* Py_ssize_t */
2673 : : case 'f': /* float */
2674 : : case 'd': /* double */
2675 : : case 'D': /* complex double */
2676 : : case 'c': /* char */
2677 : : case 'C': /* unicode char */
2678 : : case 'p': /* boolean predicate */
2679 : : case 'S': /* string object */
2680 : : case 'Y': /* string object */
2681 : : case 'U': /* unicode string object */
2682 : : {
2683 [ + - ]: 3 : if (p_va != NULL) {
2684 : 3 : (void) va_arg(*p_va, void *);
2685 : : }
2686 : 3 : break;
2687 : : }
2688 : :
2689 : : /* string codes */
2690 : :
2691 : 0 : case 'e': /* string with encoding */
2692 : : {
2693 [ # # ]: 0 : if (p_va != NULL) {
2694 : 0 : (void) va_arg(*p_va, const char *);
2695 : : }
2696 [ # # # # ]: 0 : if (!(*format == 's' || *format == 't'))
2697 : : /* after 'e', only 's' and 't' is allowed */
2698 : 0 : goto err;
2699 : 0 : format++;
2700 : : }
2701 : : /* fall through */
2702 : :
2703 : 0 : case 's': /* string */
2704 : : case 'z': /* string or None */
2705 : : case 'y': /* bytes */
2706 : : case 'w': /* buffer, read-write */
2707 : : {
2708 [ # # ]: 0 : if (p_va != NULL) {
2709 : 0 : (void) va_arg(*p_va, char **);
2710 : : }
2711 [ # # ]: 0 : if (*format == '#') {
2712 [ # # ]: 0 : if (p_va != NULL) {
2713 [ # # ]: 0 : if (!(flags & FLAG_SIZE_T)) {
2714 : 0 : return "PY_SSIZE_T_CLEAN macro must be defined for '#' formats";
2715 : : }
2716 : 0 : (void) va_arg(*p_va, Py_ssize_t *);
2717 : : }
2718 : 0 : format++;
2719 [ # # # # : 0 : } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w')
# # # # ]
2720 [ # # ]: 0 : && *format == '*')
2721 : : {
2722 : 0 : format++;
2723 : : }
2724 : 0 : break;
2725 : : }
2726 : :
2727 : 221 : case 'O': /* object */
2728 : : {
2729 [ - + ]: 221 : if (*format == '!') {
2730 : 0 : format++;
2731 [ # # ]: 0 : if (p_va != NULL) {
2732 : 0 : (void) va_arg(*p_va, PyTypeObject*);
2733 : 0 : (void) va_arg(*p_va, PyObject **);
2734 : : }
2735 : : }
2736 [ - + ]: 221 : else if (*format == '&') {
2737 : : typedef int (*converter)(PyObject *, void *);
2738 [ # # ]: 0 : if (p_va != NULL) {
2739 : 0 : (void) va_arg(*p_va, converter);
2740 : 0 : (void) va_arg(*p_va, void *);
2741 : : }
2742 : 0 : format++;
2743 : : }
2744 : : else {
2745 [ + - ]: 221 : if (p_va != NULL) {
2746 : 221 : (void) va_arg(*p_va, PyObject **);
2747 : : }
2748 : : }
2749 : 221 : break;
2750 : : }
2751 : :
2752 : 0 : case '(': /* bypass tuple, not handled at all previously */
2753 : : {
2754 : : const char *msg;
2755 : : for (;;) {
2756 [ # # ]: 0 : if (*format==')')
2757 : 0 : break;
2758 [ # # # # : 0 : if (IS_END_OF_FORMAT(*format))
# # ]
2759 : 0 : return "Unmatched left paren in format "
2760 : : "string";
2761 : 0 : msg = skipitem(&format, p_va, flags);
2762 [ # # ]: 0 : if (msg)
2763 : 0 : return msg;
2764 : : }
2765 : 0 : format++;
2766 : 0 : break;
2767 : : }
2768 : :
2769 : 0 : case ')':
2770 : 0 : return "Unmatched right paren in format string";
2771 : :
2772 : : default:
2773 : 0 : err:
2774 : 0 : return "impossible<bad format char>";
2775 : :
2776 : : }
2777 : :
2778 : 224 : *p_format = format;
2779 : 224 : return NULL;
2780 : : }
2781 : :
2782 : :
2783 : : #undef _PyArg_CheckPositional
2784 : :
2785 : : int
2786 : 11414 : _PyArg_CheckPositional(const char *name, Py_ssize_t nargs,
2787 : : Py_ssize_t min, Py_ssize_t max)
2788 : : {
2789 : : assert(min >= 0);
2790 : : assert(min <= max);
2791 : :
2792 [ + + ]: 11414 : if (nargs < min) {
2793 [ + - ]: 12 : if (name != NULL)
2794 [ + + + + ]: 12 : PyErr_Format(
2795 : : PyExc_TypeError,
2796 : : "%.200s expected %s%zd argument%s, got %zd",
2797 : : name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
2798 : : else
2799 [ # # # # ]: 0 : PyErr_Format(
2800 : : PyExc_TypeError,
2801 : : "unpacked tuple should have %s%zd element%s,"
2802 : : " but has %zd",
2803 : : (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
2804 : 12 : return 0;
2805 : : }
2806 : :
2807 [ + + ]: 11402 : if (nargs == 0) {
2808 : 854 : return 1;
2809 : : }
2810 : :
2811 [ + + ]: 10548 : if (nargs > max) {
2812 [ + - ]: 4 : if (name != NULL)
2813 [ - + + + ]: 4 : PyErr_Format(
2814 : : PyExc_TypeError,
2815 : : "%.200s expected %s%zd argument%s, got %zd",
2816 : : name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
2817 : : else
2818 [ # # # # ]: 0 : PyErr_Format(
2819 : : PyExc_TypeError,
2820 : : "unpacked tuple should have %s%zd element%s,"
2821 : : " but has %zd",
2822 : : (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
2823 : 4 : return 0;
2824 : : }
2825 : :
2826 : 10544 : return 1;
2827 : : }
2828 : :
2829 : : static int
2830 : 11398 : unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name,
2831 : : Py_ssize_t min, Py_ssize_t max, va_list vargs)
2832 : : {
2833 : : Py_ssize_t i;
2834 : : PyObject **o;
2835 : :
2836 [ - + ]: 11398 : if (!_PyArg_CheckPositional(name, nargs, min, max)) {
2837 : 0 : return 0;
2838 : : }
2839 : :
2840 [ + + ]: 28417 : for (i = 0; i < nargs; i++) {
2841 : 17019 : o = va_arg(vargs, PyObject **);
2842 : 17019 : *o = args[i];
2843 : : }
2844 : 11398 : return 1;
2845 : : }
2846 : :
2847 : : int
2848 : 10321 : PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
2849 : : {
2850 : : PyObject **stack;
2851 : : Py_ssize_t nargs;
2852 : : int retval;
2853 : : va_list vargs;
2854 : :
2855 [ - + ]: 10321 : if (!PyTuple_Check(args)) {
2856 : 0 : PyErr_SetString(PyExc_SystemError,
2857 : : "PyArg_UnpackTuple() argument list is not a tuple");
2858 : 0 : return 0;
2859 : : }
2860 : 10321 : stack = _PyTuple_ITEMS(args);
2861 : 10321 : nargs = PyTuple_GET_SIZE(args);
2862 : :
2863 : 10321 : va_start(vargs, max);
2864 : 10321 : retval = unpack_stack(stack, nargs, name, min, max, vargs);
2865 : 10321 : va_end(vargs);
2866 : 10321 : return retval;
2867 : : }
2868 : :
2869 : : int
2870 : 1077 : _PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name,
2871 : : Py_ssize_t min, Py_ssize_t max, ...)
2872 : : {
2873 : : int retval;
2874 : : va_list vargs;
2875 : :
2876 : 1077 : va_start(vargs, max);
2877 : 1077 : retval = unpack_stack(args, nargs, name, min, max, vargs);
2878 : 1077 : va_end(vargs);
2879 : 1077 : return retval;
2880 : : }
2881 : :
2882 : :
2883 : : #undef _PyArg_NoKeywords
2884 : : #undef _PyArg_NoKwnames
2885 : : #undef _PyArg_NoPositional
2886 : :
2887 : : /* For type constructors that don't take keyword args
2888 : : *
2889 : : * Sets a TypeError and returns 0 if the args/kwargs is
2890 : : * not empty, returns 1 otherwise
2891 : : */
2892 : : int
2893 : 0 : _PyArg_NoKeywords(const char *funcname, PyObject *kwargs)
2894 : : {
2895 [ # # ]: 0 : if (kwargs == NULL) {
2896 : 0 : return 1;
2897 : : }
2898 [ # # ]: 0 : if (!PyDict_CheckExact(kwargs)) {
2899 : 0 : PyErr_BadInternalCall();
2900 : 0 : return 0;
2901 : : }
2902 [ # # ]: 0 : if (PyDict_GET_SIZE(kwargs) == 0) {
2903 : 0 : return 1;
2904 : : }
2905 : :
2906 : 0 : PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
2907 : : funcname);
2908 : 0 : return 0;
2909 : : }
2910 : :
2911 : : int
2912 : 0 : _PyArg_NoPositional(const char *funcname, PyObject *args)
2913 : : {
2914 [ # # ]: 0 : if (args == NULL)
2915 : 0 : return 1;
2916 [ # # ]: 0 : if (!PyTuple_CheckExact(args)) {
2917 : 0 : PyErr_BadInternalCall();
2918 : 0 : return 0;
2919 : : }
2920 [ # # ]: 0 : if (PyTuple_GET_SIZE(args) == 0)
2921 : 0 : return 1;
2922 : :
2923 : 0 : PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments",
2924 : : funcname);
2925 : 0 : return 0;
2926 : : }
2927 : :
2928 : : int
2929 : 0 : _PyArg_NoKwnames(const char *funcname, PyObject *kwnames)
2930 : : {
2931 [ # # ]: 0 : if (kwnames == NULL) {
2932 : 0 : return 1;
2933 : : }
2934 : :
2935 : : assert(PyTuple_CheckExact(kwnames));
2936 : :
2937 [ # # ]: 0 : if (PyTuple_GET_SIZE(kwnames) == 0) {
2938 : 0 : return 1;
2939 : : }
2940 : :
2941 : 0 : PyErr_Format(PyExc_TypeError, "%s() takes no keyword arguments", funcname);
2942 : 0 : return 0;
2943 : : }
2944 : :
2945 : : void
2946 : 25 : _PyArg_Fini(void)
2947 : : {
2948 : 25 : struct _PyArg_Parser *tmp, *s = _PyRuntime.getargs.static_parsers;
2949 [ + + ]: 113 : while (s) {
2950 : 88 : tmp = s->next;
2951 : 88 : s->next = NULL;
2952 : 88 : parser_clear(s);
2953 : 88 : s = tmp;
2954 : : }
2955 : 25 : _PyRuntime.getargs.static_parsers = NULL;
2956 : 25 : }
2957 : :
2958 : : #ifdef __cplusplus
2959 : : };
2960 : : #endif
|