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