this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include <cassert>
3#include <climits>
4#include <cstdarg>
5
6#include "cpython-data.h"
7#include "cpython-func.h"
8
9#include "runtime.h"
10
11namespace py {
12
13#define FLAG_COMPAT 1
14#define FLAG_SIZE_T 2
15
16typedef int (*destr_t)(PyObject*, void*);
17
18// Keep track of "objects" that have been allocated or initialized and
19// which will need to be deallocated or cleaned up somehow if overall
20// parsing fails.
21
22typedef struct {
23 void* item;
24 destr_t destructor;
25} freelistentry_t;
26
27typedef struct {
28 freelistentry_t* entries;
29 int first_available;
30 int entries_malloced;
31} freelist_t;
32
33#define STATIC_FREELIST_ENTRIES 8
34
35static const int kMaxSmallArraySize = 16;
36
37// Forward
38static int vGetArgs1Impl(PyObject* args, PyObject* const* stack,
39 Py_ssize_t nargs, const char* format, va_list* p_va,
40 int flags);
41static int vgetargs1(PyObject*, const char*, va_list*, int);
42static void seterror(Py_ssize_t, const char*, int*, const char*, const char*);
43static const char* convertitem(PyObject*, const char**, va_list*, int, int*,
44 char*, size_t, freelist_t*);
45static const char* converttuple(PyObject*, const char**, va_list*, int, int*,
46 char*, size_t, int, freelist_t*);
47static const char* convertsimple(PyObject*, const char**, va_list*, int, char*,
48 size_t, freelist_t*);
49static Py_ssize_t convertbuffer(PyObject*, void const** p, const char**);
50static int getbuffer(PyObject*, Py_buffer*, const char**);
51
52static int vgetargskeywords(PyObject*, PyObject*, const char*, char**, va_list*,
53 int);
54
55static int vGetArgsKeywordsFast(PyObject*, PyObject*, struct _PyArg_Parser*,
56 va_list*, int);
57static int vGetArgsKeywordsFastImpl(PyObject* const* args, Py_ssize_t nargs,
58 PyObject* keywords, PyObject* kwnames,
59 struct _PyArg_Parser* parser, va_list* p_va,
60 int flags);
61static bool parserInit(struct _PyArg_Parser* parser, int* keyword_count);
62static PyObject* findKeyword(PyObject* kwnames, PyObject* const* kwstack,
63 const char* key);
64static const char* skipitem(const char**, va_list*, int);
65
66PY_EXPORT int PyArg_Parse(PyObject* args, const char* format, ...) {
67 int retval;
68 va_list va;
69
70 va_start(va, format);
71 retval = vgetargs1(args, format, &va, FLAG_COMPAT);
72 va_end(va);
73 return retval;
74}
75
76PY_EXPORT int _PyArg_Parse_SizeT(PyObject* args, const char* format, ...) {
77 int retval;
78 va_list va;
79
80 va_start(va, format);
81 retval = vgetargs1(args, format, &va, FLAG_COMPAT | FLAG_SIZE_T);
82 va_end(va);
83 return retval;
84}
85
86PY_EXPORT int PyArg_ParseTuple(PyObject* args, const char* format, ...) {
87 int retval;
88 va_list va;
89
90 va_start(va, format);
91 retval = vgetargs1(args, format, &va, 0);
92 va_end(va);
93 return retval;
94}
95
96PY_EXPORT int _PyArg_ParseTuple_SizeT(PyObject* args, const char* format, ...) {
97 int retval;
98 va_list va;
99
100 va_start(va, format);
101 retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
102 va_end(va);
103 return retval;
104}
105
106PY_EXPORT int _PyArg_ParseStack(PyObject* const* args, Py_ssize_t nargs,
107 const char* format, ...) {
108 va_list va;
109 va_start(va, format);
110 int retval = vGetArgs1Impl(nullptr, args, nargs, format, &va, 0);
111 va_end(va);
112 return retval;
113}
114
115PY_EXPORT int _PyArg_ParseStack_SizeT(PyObject* const* args, Py_ssize_t nargs,
116 const char* format, ...) {
117 va_list va;
118 va_start(va, format);
119 int retval = vGetArgs1Impl(nullptr, args, nargs, format, &va, FLAG_SIZE_T);
120 va_end(va);
121 return retval;
122}
123
124PY_EXPORT int PyArg_VaParse(PyObject* args, const char* format, va_list va) {
125 va_list lva;
126 int retval;
127
128 va_copy(lva, va);
129
130 retval = vgetargs1(args, format, &lva, 0);
131 va_end(lva);
132 return retval;
133}
134
135PY_EXPORT int _PyArg_VaParse_SizeT(PyObject* args, const char* format,
136 va_list va) {
137 va_list lva;
138 int retval;
139
140 va_copy(lva, va);
141
142 retval = vgetargs1(args, format, &lva, FLAG_SIZE_T);
143 va_end(lva);
144 return retval;
145}
146
147// Handle cleanup of allocated memory in case of exception
148
149static int cleanup_ptr(PyObject*, void* ptr) {
150 if (ptr) {
151 PyMem_FREE(ptr);
152 }
153 return 0;
154}
155
156static int cleanup_buffer(PyObject*, void* ptr) {
157 Py_buffer* buf = static_cast<Py_buffer*>(ptr);
158 if (buf) {
159 PyBuffer_Release(buf);
160 }
161 return 0;
162}
163
164static int addcleanup(void* ptr, freelist_t* freelist, destr_t destructor) {
165 int index;
166
167 index = freelist->first_available;
168 freelist->first_available += 1;
169
170 freelist->entries[index].item = ptr;
171 freelist->entries[index].destructor = destructor;
172
173 return 0;
174}
175
176static int cleanreturn(int retval, freelist_t* freelist) {
177 int index;
178
179 if (retval == 0) {
180 // A failure occurred, therefore execute all of the cleanup
181 // functions.
182
183 for (index = 0; index < freelist->first_available; ++index) {
184 freelist->entries[index].destructor(nullptr,
185 freelist->entries[index].item);
186 }
187 }
188 if (freelist->entries_malloced) PyMem_FREE(freelist->entries);
189 return retval;
190}
191
192static int vGetArgs1Impl(PyObject* compat_args, PyObject* const* stack,
193 Py_ssize_t nargs, const char* format, va_list* p_va,
194 int flags) {
195 DCHECK(nargs == 0 || stack != nullptr,
196 "if nargs == 0, stack must be nullptr");
197
198 int compat = flags & FLAG_COMPAT;
199 flags = flags & ~FLAG_COMPAT;
200
201 int endfmt = 0;
202 const char* formatsave = format;
203 const char* fname = nullptr;
204 int level = 0;
205 int max = 0;
206 const char* message = nullptr;
207 int min = -1;
208 while (endfmt == 0) {
209 int c = *format++;
210 switch (c) {
211 case '(':
212 if (level == 0) max++;
213 level++;
214 if (level >= 30) {
215 Py_FatalError(
216 "too many tuple nesting levels "
217 "in argument format string");
218 }
219 break;
220 case ')':
221 if (level == 0) {
222 Py_FatalError("excess ')' in getargs format");
223 } else {
224 level--;
225 }
226 break;
227 case '\0':
228 endfmt = 1;
229 break;
230 case ':':
231 fname = format;
232 endfmt = 1;
233 break;
234 case ';':
235 message = format;
236 endfmt = 1;
237 break;
238 case '|':
239 if (level == 0) min = max;
240 break;
241 default:
242 if (level == 0 && Py_ISALPHA(Py_CHARMASK(c)) && c != 'e') {
243 /* skip encoded */
244 max++;
245 }
246 break;
247 }
248 }
249
250 if (level != 0) Py_FatalError(/* '(' */ "missing ')' in getargs format");
251
252 if (min < 0) min = max;
253
254 freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
255 freelist_t freelist;
256 freelist.entries = static_entries;
257 freelist.first_available = 0;
258 freelist.entries_malloced = 0;
259 if (max > STATIC_FREELIST_ENTRIES) {
260 freelist.entries = PyMem_NEW(freelistentry_t, max);
261 if (freelist.entries == nullptr) {
262 PyErr_NoMemory();
263 return 0;
264 }
265 freelist.entries_malloced = 1;
266 }
267
268 format = formatsave;
269 int levels[32];
270 const char* msg;
271 char msgbuf[256];
272 if (compat) {
273 if (max == 0) {
274 if (compat_args == nullptr) return 1;
275 PyErr_Format(PyExc_TypeError, "%.200s%s takes no arguments",
276 fname == nullptr ? "function" : fname,
277 fname == nullptr ? "" : "()");
278 return cleanreturn(0, &freelist);
279 }
280 if (min == 1 && max == 1) {
281 if (compat_args == nullptr) {
282 PyErr_Format(PyExc_TypeError, "%.200s%s takes at least one argument",
283 fname == nullptr ? "function" : fname,
284 fname == nullptr ? "" : "()");
285 return cleanreturn(0, &freelist);
286 }
287 msg = convertitem(compat_args, &format, p_va, flags, levels, msgbuf,
288 sizeof(msgbuf), &freelist);
289 if (msg == nullptr) return cleanreturn(1, &freelist);
290 seterror(levels[0], msg, levels + 1, fname, message);
291 return cleanreturn(0, &freelist);
292 }
293 Thread::current()->raiseWithFmt(
294 LayoutId::kSystemError, "old style getargs format uses new features");
295 return cleanreturn(0, &freelist);
296 }
297
298 if (nargs < min || max < nargs) {
299 if (message == nullptr) {
300 PyErr_Format(
301 PyExc_TypeError, "%.150s%s takes %s %d argument%s (%zd given)",
302 fname == nullptr ? "function" : fname, fname == nullptr ? "" : "()",
303 min == max ? "exactly" : nargs < min ? "at least" : "at most",
304 nargs < min ? min : max, (nargs < min ? min : max) == 1 ? "" : "s",
305 nargs);
306 } else {
307 Thread::current()->raiseWithFmt(LayoutId::kTypeError, message);
308 }
309 return cleanreturn(0, &freelist);
310 }
311
312 for (Py_ssize_t i = 0; i < nargs; i++) {
313 if (*format == '|') format++;
314 msg = convertitem(stack[i], &format, p_va, flags, levels, msgbuf,
315 sizeof(msgbuf), &freelist);
316 if (msg) {
317 seterror(i + 1, msg, levels, fname, message);
318 return cleanreturn(0, &freelist);
319 }
320 }
321
322 if (*format != '\0' && !Py_ISALPHA(Py_CHARMASK(*format)) && *format != '(' &&
323 *format != '|' && *format != ':' && *format != ';') {
324 PyErr_Format(PyExc_SystemError, "bad format string: %.200s", formatsave);
325 return cleanreturn(0, &freelist);
326 }
327
328 return cleanreturn(1, &freelist);
329}
330
331static int vgetargs1(PyObject* args, const char* format, va_list* p_va,
332 int flags) {
333 if (flags & FLAG_COMPAT) {
334 return vGetArgs1Impl(args, nullptr, 0, format, p_va, flags);
335 }
336 DCHECK(args != nullptr, "args must be non-NULL");
337
338 if (!PyTuple_Check(args)) {
339 Thread::current()->raiseWithFmt(
340 LayoutId::kSystemError,
341 "new style getargs format but argument is not a tuple");
342 return 0;
343 }
344
345 PyObject* small_array[kMaxSmallArraySize];
346 Py_ssize_t nargs = PyTuple_Size(args);
347 PyObject** array =
348 nargs <= kMaxSmallArraySize ? small_array : new PyObject*[nargs];
349 for (Py_ssize_t i = 0; i < nargs; i++) {
350 array[i] = PyTuple_GET_ITEM(args, i);
351 }
352 int retval = vGetArgs1Impl(args, array, nargs, format, p_va, flags);
353 if (array != small_array) {
354 delete[] array;
355 }
356 return retval;
357}
358
359static void seterror(Py_ssize_t iarg, const char* msg, int* levels,
360 const char* fname, const char* message) {
361 char buf[512];
362 int i;
363 char* p = buf;
364
365 if (PyErr_Occurred()) return;
366 if (message == nullptr) {
367 if (fname != nullptr) {
368 PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
369 p += std::strlen(p);
370 }
371 if (iarg != 0) {
372 PyOS_snprintf(p, sizeof(buf) - (p - buf),
373 "argument %" PY_FORMAT_SIZE_T "d", iarg);
374 i = 0;
375 p += std::strlen(p);
376 while (i < 32 && levels[i] > 0 && static_cast<int>(p - buf) < 220) {
377 PyOS_snprintf(p, sizeof(buf) - (p - buf), ", item %d", levels[i] - 1);
378 p += std::strlen(p);
379 i++;
380 }
381 } else {
382 PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
383 p += std::strlen(p);
384 }
385 PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
386 message = buf;
387 }
388 if (msg[0] == '(') {
389 Thread::current()->raiseWithFmt(LayoutId::kSystemError, message);
390 } else {
391 Thread::current()->raiseWithFmt(LayoutId::kTypeError, message);
392 }
393}
394
395// Convert a tuple argument.
396// On entry, *p_format points to the character _after_ the opening '('.
397// On successful exit, *p_format points to the closing ')'.
398// If successful:
399// *p_format and *p_va are updated,
400// *levels and *msgbuf are untouched,
401// and nullptr is returned.
402// If the argument is invalid:
403// *p_format is unchanged,
404// *p_va is undefined,
405// *levels is a 0-terminated list of item numbers,
406// *msgbuf contains an error message, whose format is:
407// "must be <typename1>, not <typename2>", where:
408// <typename1> is the name of the expected type, and
409// <typename2> is the name of the actual type,
410// and msgbuf is returned.
411static const char* converttuple(PyObject* arg, const char** p_format,
412 va_list* p_va, int flags, int* levels,
413 char* msgbuf, size_t bufsize, int toplevel,
414 freelist_t* freelist) {
415 int level = 0;
416 int n = 0;
417 const char* format = *p_format;
418 int i;
419 Py_ssize_t len;
420
421 for (;;) {
422 int c = *format++;
423 if (c == '(') {
424 if (level == 0) n++;
425 level++;
426 } else if (c == ')') {
427 if (level == 0) break;
428 level--;
429 } else if (c == ':' || c == ';' || c == '\0') {
430 break;
431 } else if (level == 0 && Py_ISALPHA(Py_CHARMASK(c))) {
432 n++;
433 }
434 }
435
436 if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
437 levels[0] = 0;
438 PyOS_snprintf(msgbuf, bufsize,
439 toplevel ? "expected %d arguments, not %.50s"
440 : "must be %d-item sequence, not %.50s",
441 n, arg == Py_None ? "None" : _PyType_Name(Py_TYPE(arg)));
442 return msgbuf;
443 }
444
445 len = PySequence_Size(arg);
446 if (len != n) {
447 levels[0] = 0;
448 if (toplevel) {
449 PyOS_snprintf(msgbuf, bufsize,
450 "expected %d arguments, not %" PY_FORMAT_SIZE_T "d", n,
451 len);
452 } else {
453 PyOS_snprintf(msgbuf, bufsize,
454 "must be sequence of length %d, "
455 "not %" PY_FORMAT_SIZE_T "d",
456 n, len);
457 }
458 return msgbuf;
459 }
460
461 format = *p_format;
462 for (i = 0; i < n; i++) {
463 const char* msg;
464 PyObject* item;
465 item = PySequence_GetItem(arg, i);
466 if (item == nullptr) {
467 PyErr_Clear();
468 levels[0] = i + 1;
469 levels[1] = 0;
470 strncpy(msgbuf, "is not retrievable", bufsize);
471 return msgbuf;
472 }
473 msg = convertitem(item, &format, p_va, flags, levels + 1, msgbuf, bufsize,
474 freelist);
475 // PySequence_GetItem calls tp->sq_item, which INCREFs
476 Py_XDECREF(item);
477 if (msg != nullptr) {
478 levels[0] = i + 1;
479 return msg;
480 }
481 }
482
483 *p_format = format;
484 return nullptr;
485}
486
487// Convert a single item.
488static const char* convertitem(PyObject* arg, const char** p_format,
489 va_list* p_va, int flags, int* levels,
490 char* msgbuf, size_t bufsize,
491 freelist_t* freelist) {
492 const char* msg;
493 const char* format = *p_format;
494
495 if (*format == '(') {
496 format++;
497 msg = converttuple(arg, &format, p_va, flags, levels, msgbuf, bufsize, 0,
498 freelist);
499 if (msg == nullptr) format++;
500 } else {
501 msg = convertsimple(arg, &format, p_va, flags, msgbuf, bufsize, freelist);
502 if (msg != nullptr) levels[0] = 0;
503 }
504 if (msg == nullptr) *p_format = format;
505 return msg;
506}
507
508// Format an error message generated by convertsimple().
509static const char* converterr(const char* expected, PyObject* arg, char* msgbuf,
510 size_t bufsize) {
511 assert(expected != nullptr);
512 assert(arg != nullptr);
513 if (expected[0] == '(') {
514 PyOS_snprintf(msgbuf, bufsize, "%.100s", expected);
515 } else {
516 PyOS_snprintf(msgbuf, bufsize, "must be %.50s, not %.50s", expected,
517 arg == Py_None ? "None" : _PyType_Name(Py_TYPE(arg)));
518 }
519 return msgbuf;
520}
521
522#define CONV_UNICODE "(unicode conversion error)"
523
524// Explicitly check for float arguments when integers are expected.
525// Return 1 for error, 0 if ok.
526static int float_argument_error(PyObject* arg) {
527 if (PyFloat_Check(arg)) {
528 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
529 "integer argument expected, got float");
530 return 1;
531 }
532 return 0;
533}
534
535// Convert a non-tuple argument. Return nullptr if conversion went OK,
536// or a string with a message describing the failure. The message is
537// formatted as "must be <desired type>, not <actual type>".
538// When failing, an exception may or may not have been raised.
539// Don't call if a tuple is expected.
540//
541// When you add new format codes, please don't forget poor skipitem() below.
542static const char* convertsimple(PyObject* arg, const char** p_format,
543 va_list* p_va, int flags, char* msgbuf,
544 size_t bufsize, freelist_t* freelist) {
545 // For # codes
546#define FETCH_SIZE \
547 int* q = nullptr; \
548 Py_ssize_t* q2 = nullptr; \
549 if (flags & FLAG_SIZE_T) \
550 q2 = va_arg(*p_va, Py_ssize_t*); \
551 else \
552 q = va_arg(*p_va, int*);
553#define STORE_SIZE(s) \
554 if (flags & FLAG_SIZE_T) \
555 *q2 = s; \
556 else { \
557 if (INT_MAX < s) { \
558 Thread::current()->raiseWithFmt(LayoutId::kOverflowError, \
559 "size does not fit in an int"); \
560 return converterr("", arg, msgbuf, bufsize); \
561 } \
562 *q = (int)s; \
563 }
564#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2 : *q)
565#define RETURN_ERR_OCCURRED return msgbuf
566
567 const char* format = *p_format;
568 char c = *format++;
569
570 switch (c) {
571 case 'b': { // unsigned byte -- very short int
572 char* p = va_arg(*p_va, char*);
573 long ival;
574 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
575 ival = PyLong_AsLong(arg);
576 if (ival == -1 && PyErr_Occurred()) {
577 RETURN_ERR_OCCURRED;
578 }
579 if (ival < 0) {
580 Thread::current()->raiseWithFmt(
581 LayoutId::kOverflowError,
582 "unsigned byte integer is less than minimum");
583 RETURN_ERR_OCCURRED;
584 }
585 if (ival > UCHAR_MAX) {
586 Thread::current()->raiseWithFmt(
587 LayoutId::kOverflowError,
588 "unsigned byte integer is greater than maximum");
589 RETURN_ERR_OCCURRED;
590 }
591 *p = static_cast<unsigned char>(ival);
592 break;
593 }
594
595 case 'B': { // byte sized bitfield - both signed and unsigned
596 // values allowed
597 char* p = va_arg(*p_va, char*);
598 long ival;
599 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
600 ival = PyLong_AsUnsignedLongMask(arg);
601 if (ival == -1 && PyErr_Occurred()) {
602 RETURN_ERR_OCCURRED;
603 }
604 *p = static_cast<unsigned char>(ival);
605 break;
606 }
607
608 case 'h': { // signed short int
609 short* p = va_arg(*p_va, short*);
610 long ival;
611 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
612 ival = PyLong_AsLong(arg);
613 if (ival == -1 && PyErr_Occurred()) {
614 RETURN_ERR_OCCURRED;
615 }
616 if (ival < SHRT_MIN) {
617 Thread::current()->raiseWithFmt(
618 LayoutId::kOverflowError,
619 "signed short integer is less than minimum");
620 RETURN_ERR_OCCURRED;
621 }
622 if (ival > SHRT_MAX) {
623 Thread::current()->raiseWithFmt(
624 LayoutId::kOverflowError,
625 "signed short integer is greater than maximum");
626 RETURN_ERR_OCCURRED;
627 }
628 *p = static_cast<short>(ival);
629 break;
630 }
631
632 case 'H': { // short int sized bitfield, both signed and
633 // unsigned allowed
634 unsigned short* p = va_arg(*p_va, unsigned short*);
635 long ival;
636 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
637 ival = PyLong_AsUnsignedLongMask(arg);
638 if (ival == -1 && PyErr_Occurred()) {
639 RETURN_ERR_OCCURRED;
640 }
641 *p = static_cast<unsigned short>(ival);
642 break;
643 }
644
645 case 'i': { // signed int
646 int* p = va_arg(*p_va, int*);
647 long ival;
648 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
649 ival = PyLong_AsLong(arg);
650 if (ival == -1 && PyErr_Occurred()) {
651 RETURN_ERR_OCCURRED;
652 }
653 if (ival > INT_MAX) {
654 Thread::current()->raiseWithFmt(
655 LayoutId::kOverflowError, "signed integer is greater than maximum");
656 RETURN_ERR_OCCURRED;
657 }
658 if (ival < INT_MIN) {
659 Thread::current()->raiseWithFmt(LayoutId::kOverflowError,
660 "signed integer is less than minimum");
661 RETURN_ERR_OCCURRED;
662 }
663 *p = ival;
664 break;
665 }
666
667 case 'I': { // int sized bitfield, both signed and
668 // unsigned allowed
669 unsigned int* p = va_arg(*p_va, unsigned int*);
670 unsigned int ival;
671 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
672 ival = static_cast<unsigned int>(PyLong_AsUnsignedLongMask(arg));
673 if (ival == -1U && PyErr_Occurred()) {
674 RETURN_ERR_OCCURRED;
675 }
676 *p = ival;
677 break;
678 }
679
680 case 'n': // Py_ssize_t
681 {
682 PyObject* iobj;
683 Py_ssize_t* p = va_arg(*p_va, Py_ssize_t*);
684 Py_ssize_t ival = -1;
685 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
686 iobj = PyNumber_Index(arg);
687 if (iobj != nullptr) {
688 ival = PyLong_AsSsize_t(iobj);
689 Py_DECREF(iobj);
690 }
691 if (ival == -1 && PyErr_Occurred()) RETURN_ERR_OCCURRED;
692 *p = ival;
693 break;
694 }
695 case 'l': { // long int
696 long* p = va_arg(*p_va, long*);
697 long ival;
698 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
699 ival = PyLong_AsLong(arg);
700 if (ival == -1 && PyErr_Occurred()) {
701 RETURN_ERR_OCCURRED;
702 }
703 *p = ival;
704 break;
705 }
706
707 case 'k': { // long sized bitfield
708 unsigned long* p = va_arg(*p_va, unsigned long*);
709 unsigned long ival;
710 if (!PyLong_Check(arg)) {
711 return converterr("int", arg, msgbuf, bufsize);
712 }
713 ival = PyLong_AsUnsignedLongMask(arg);
714 *p = ival;
715 break;
716 }
717
718 case 'L': { // long long
719 long long* p = va_arg(*p_va, long long*);
720 long long ival;
721 if (float_argument_error(arg)) RETURN_ERR_OCCURRED;
722 ival = PyLong_AsLongLong(arg);
723 if (ival == -1LL && PyErr_Occurred()) {
724 RETURN_ERR_OCCURRED;
725 }
726 *p = ival;
727 break;
728 }
729
730 case 'K': { // long long sized bitfield
731 unsigned long long* p = va_arg(*p_va, unsigned long long*);
732 unsigned long long ival;
733 if (!PyLong_Check(arg)) {
734 return converterr("int", arg, msgbuf, bufsize);
735 }
736 ival = PyLong_AsUnsignedLongLongMask(arg);
737 *p = ival;
738 break;
739 }
740
741 case 'f': { // float
742 float* p = va_arg(*p_va, float*);
743 double dval = PyFloat_AsDouble(arg);
744 if (PyErr_Occurred()) {
745 RETURN_ERR_OCCURRED;
746 }
747 *p = static_cast<float>(dval);
748 break;
749 }
750
751 case 'd': { // double
752 double* p = va_arg(*p_va, double*);
753 double dval = PyFloat_AsDouble(arg);
754 if (PyErr_Occurred()) {
755 RETURN_ERR_OCCURRED;
756 }
757 *p = dval;
758 break;
759 }
760
761 case 'D': { // complex double
762 Py_complex* p = va_arg(*p_va, Py_complex*);
763 Py_complex cval;
764 cval = PyComplex_AsCComplex(arg);
765 if (PyErr_Occurred()) {
766 RETURN_ERR_OCCURRED;
767 }
768 *p = cval;
769 break;
770 }
771
772 case 'c': { // char
773 char* p = va_arg(*p_va, char*);
774 if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) {
775 *p = PyBytes_AS_STRING(arg)[0];
776 } else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1) {
777 *p = PyByteArray_AS_STRING(arg)[0];
778 } else {
779 return converterr("a byte string of length 1", arg, msgbuf, bufsize);
780 }
781 break;
782 }
783
784 case 'C': { // unicode char
785 int* p = va_arg(*p_va, int*);
786
787 if (!PyUnicode_Check(arg)) {
788 return converterr("a unicode character", arg, msgbuf, bufsize);
789 }
790
791 if (PyUnicode_READY(arg)) RETURN_ERR_OCCURRED;
792
793 if (PyUnicode_GET_LENGTH(arg) != 1) {
794 return converterr("a unicode character", arg, msgbuf, bufsize);
795 }
796
797 *p = PyUnicode_READ_CHAR(arg, 0);
798 break;
799 }
800
801 case 'p': { // boolean *p*redicate
802 int* p = va_arg(*p_va, int*);
803 int val = PyObject_IsTrue(arg);
804 if (val > 0) {
805 *p = 1;
806 } else if (val == 0) {
807 *p = 0;
808 } else {
809 RETURN_ERR_OCCURRED;
810 }
811 break;
812 }
813
814 // XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
815 // need to be cleaned up!
816
817 case 'y': { // any bytes-like object
818 void const** p =
819 reinterpret_cast<void const**>(va_arg(*p_va, char const**));
820 const char* buf;
821 Py_ssize_t count;
822 if (*format == '*') {
823 if (getbuffer(arg, reinterpret_cast<Py_buffer*>(p), &buf) < 0) {
824 return converterr(buf, arg, msgbuf, bufsize);
825 }
826 format++;
827 if (addcleanup(p, freelist, cleanup_buffer)) {
828 return converterr("(cleanup problem)", arg, msgbuf, bufsize);
829 }
830 break;
831 }
832 count = convertbuffer(arg, p, &buf);
833 if (count < 0) {
834 return converterr(buf, arg, msgbuf, bufsize);
835 }
836 if (*format == '#') {
837 FETCH_SIZE;
838 STORE_SIZE(count);
839 format++;
840 } else {
841 if (std::strlen(static_cast<const char*>(*p)) !=
842 static_cast<size_t>(count)) {
843 Thread::current()->raiseWithFmt(LayoutId::kValueError,
844 "embedded null byte");
845 RETURN_ERR_OCCURRED;
846 }
847 }
848 break;
849 }
850
851 case 's': // text string or bytes-like object
852 case 'z': // text string, bytes-like object or None
853 {
854 if (*format == '*') {
855 // "s*" or "z*"
856 Py_buffer* p = va_arg(*p_va, Py_buffer*);
857
858 if (c == 'z' && arg == Py_None) {
859 PyBuffer_FillInfo(p, nullptr, nullptr, 0, 1, 0);
860 } else if (PyUnicode_Check(arg)) {
861 Py_ssize_t len;
862 const char* sarg = PyUnicode_AsUTF8AndSize(arg, &len);
863 if (sarg == nullptr) {
864 return converterr(CONV_UNICODE, arg, msgbuf, bufsize);
865 }
866 // This const_cast is gross, but FillInfo should only ever read from
867 // this arg.
868 PyBuffer_FillInfo(p, arg, const_cast<char*>(sarg), len, 1, 0);
869 } else { // any bytes-like object
870 const char* buf;
871 if (getbuffer(arg, p, &buf) < 0) {
872 return converterr(buf, arg, msgbuf, bufsize);
873 }
874 }
875 if (addcleanup(p, freelist, cleanup_buffer)) {
876 return converterr("(cleanup problem)", arg, msgbuf, bufsize);
877 }
878 format++;
879 } else if (*format == '#') { // a string or read-only bytes-like object
880 // "s#" or "z#"
881 void const** p =
882 reinterpret_cast<void const**>(va_arg(*p_va, char const**));
883 FETCH_SIZE;
884
885 if (c == 'z' && arg == Py_None) {
886 *p = nullptr;
887 STORE_SIZE(0);
888 } else if (PyUnicode_Check(arg)) {
889 Py_ssize_t len;
890 const char* sarg = PyUnicode_AsUTF8AndSize(arg, &len);
891 if (sarg == nullptr) {
892 return converterr(CONV_UNICODE, arg, msgbuf, bufsize);
893 }
894 *p = sarg;
895 STORE_SIZE(len);
896 } else { // read-only bytes-like object
897 // XXX Really?
898 const char* buf;
899 Py_ssize_t count = convertbuffer(arg, p, &buf);
900 if (count < 0) return converterr(buf, arg, msgbuf, bufsize);
901 STORE_SIZE(count);
902 }
903 format++;
904 } else {
905 // "s" or "z"
906 char const** p = va_arg(*p_va, char const**);
907 Py_ssize_t len;
908
909 if (c == 'z' && arg == Py_None) {
910 *p = nullptr;
911 } else if (PyUnicode_Check(arg)) {
912 const char* sarg = PyUnicode_AsUTF8AndSize(arg, &len);
913 if (sarg == nullptr) {
914 return converterr(CONV_UNICODE, arg, msgbuf, bufsize);
915 }
916 if (std::strlen(sarg) != static_cast<size_t>(len)) {
917 Thread::current()->raiseWithFmt(LayoutId::kValueError,
918 "embedded null character");
919 RETURN_ERR_OCCURRED;
920 }
921 *p = sarg;
922 } else {
923 return converterr(c == 'z' ? "str or None" : "str", arg, msgbuf,
924 bufsize);
925 }
926 }
927 break;
928 }
929
930 case 'u': // raw unicode buffer (Py_UNICODE *)
931 case 'Z': // raw unicode buffer or None
932 {
933 Py_UNICODE** p = va_arg(*p_va, Py_UNICODE**);
934
935 if (*format == '#') {
936 // "u#" or "Z#"
937 FETCH_SIZE;
938
939 if (c == 'Z' && arg == Py_None) {
940 *p = nullptr;
941 STORE_SIZE(0);
942 } else if (PyUnicode_Check(arg)) {
943 Py_ssize_t len;
944 *p = PyUnicode_AsUnicodeAndSize(arg, &len);
945 if (*p == nullptr) RETURN_ERR_OCCURRED;
946 STORE_SIZE(len);
947 } else {
948 return converterr(c == 'Z' ? "str or None" : "str", arg, msgbuf,
949 bufsize);
950 }
951 format++;
952 } else {
953 // "u" or "Z"
954 if (c == 'Z' && arg == Py_None) {
955 *p = nullptr;
956 } else if (PyUnicode_Check(arg)) {
957 Py_ssize_t len;
958 *p = PyUnicode_AsUnicodeAndSize(arg, &len);
959 if (*p == nullptr) RETURN_ERR_OCCURRED;
960 if (Py_UNICODE_strlen(*p) != static_cast<size_t>(len)) {
961 Thread::current()->raiseWithFmt(LayoutId::kValueError,
962 "embedded null character");
963 RETURN_ERR_OCCURRED;
964 }
965 } else {
966 return converterr(c == 'Z' ? "str or None" : "str", arg, msgbuf,
967 bufsize);
968 }
969 }
970 break;
971 }
972
973 case 'e': { // encoded string
974 char** buffer;
975 const char* encoding;
976 PyObject* s;
977 int recode_strings;
978 Py_ssize_t size;
979 const char* ptr;
980
981 // Get 'e' parameter: the encoding name
982 encoding = va_arg(*p_va, const char*);
983 if (encoding == nullptr) encoding = PyUnicode_GetDefaultEncoding();
984
985 // Get output buffer parameter:
986 // 's' (recode all objects via Unicode) or
987 // 't' (only recode non-string objects)
988 if (*format == 's') {
989 recode_strings = 1;
990 } else if (*format == 't') {
991 recode_strings = 0;
992 } else {
993 return converterr("(unknown parser marker combination)", arg, msgbuf,
994 bufsize);
995 }
996 buffer = va_arg(*p_va, char**);
997 format++;
998 if (buffer == nullptr) {
999 return converterr("(buffer is nullptr)", arg, msgbuf, bufsize);
1000 }
1001 // Encode object
1002 if (!recode_strings && (PyBytes_Check(arg) || PyByteArray_Check(arg))) {
1003 s = arg;
1004 Py_INCREF(s);
1005 if (PyObject_AsCharBuffer(s, &ptr, &size) < 0) {
1006 return converterr("(AsCharBuffer failed)", arg, msgbuf, bufsize);
1007 }
1008 } else if (PyUnicode_Check(arg)) {
1009 // Encode object; use default error handling
1010 s = PyUnicode_AsEncodedString(arg, encoding, nullptr);
1011 if (s == nullptr) {
1012 return converterr("(encoding failed)", arg, msgbuf, bufsize);
1013 }
1014 assert(PyBytes_Check(s));
1015 size = PyBytes_GET_SIZE(s);
1016 ptr = PyBytes_AS_STRING(s);
1017 if (ptr == nullptr) ptr = "";
1018 } else {
1019 return converterr(recode_strings ? "str" : "str, bytes or bytearray",
1020 arg, msgbuf, bufsize);
1021 }
1022
1023 // Write output; output is guaranteed to be 0-terminated
1024 if (*format == '#') {
1025 // Using buffer length parameter '#':
1026 //
1027 // - if *buffer is nullptr, a new buffer of the
1028 // needed size is allocated and the data
1029 // copied into it; *buffer is updated to point
1030 // to the new buffer; the caller is
1031 // responsible for PyMem_Free()ing it after
1032 // usage
1033 //
1034 // - if *buffer is not nullptr, the data is
1035 // copied to *buffer; *buffer_len has to be
1036 // set to the size of the buffer on input;
1037 // buffer overflow is signalled with an error;
1038 // buffer has to provide enough room for the
1039 // encoded string plus the trailing 0-byte
1040 //
1041 // - in both cases, *buffer_len is updated to
1042 // the size of the buffer /excluding/ the
1043 // trailing 0-byte
1044 FETCH_SIZE;
1045
1046 format++;
1047 if (q == nullptr && q2 == nullptr) {
1048 Py_DECREF(s);
1049 return converterr("(buffer_len is nullptr)", arg, msgbuf, bufsize);
1050 }
1051 if (*buffer == nullptr) {
1052 *buffer = PyMem_NEW(char, size + 1);
1053 if (*buffer == nullptr) {
1054 Py_DECREF(s);
1055 PyErr_NoMemory();
1056 RETURN_ERR_OCCURRED;
1057 }
1058 if (addcleanup(*buffer, freelist, cleanup_ptr)) {
1059 Py_DECREF(s);
1060 return converterr("(cleanup problem)", arg, msgbuf, bufsize);
1061 }
1062 } else {
1063 if (size + 1 > BUFFER_LEN) {
1064 Py_DECREF(s);
1065 PyErr_Format(PyExc_ValueError,
1066 "encoded string too long "
1067 "(%zd, maximum length %zd)",
1068 size, static_cast<Py_ssize_t>(BUFFER_LEN - 1));
1069 RETURN_ERR_OCCURRED;
1070 }
1071 }
1072 memcpy(*buffer, ptr, size + 1);
1073 STORE_SIZE(size);
1074 } else {
1075 // Using a 0-terminated buffer:
1076 //
1077 // - the encoded string has to be 0-terminated
1078 // for this variant to work; if it is not, an
1079 // error raised
1080 //
1081 // - a new buffer of the needed size is
1082 // allocated and the data copied into it;
1083 // *buffer is updated to point to the new
1084 // buffer; the caller is responsible for
1085 // PyMem_Free()ing it after usage
1086 if (static_cast<Py_ssize_t>(std::strlen(ptr)) != size) {
1087 Py_DECREF(s);
1088 return converterr("encoded string without null bytes", arg, msgbuf,
1089 bufsize);
1090 }
1091 *buffer = PyMem_NEW(char, size + 1);
1092 if (*buffer == nullptr) {
1093 Py_DECREF(s);
1094 PyErr_NoMemory();
1095 RETURN_ERR_OCCURRED;
1096 }
1097 if (addcleanup(*buffer, freelist, cleanup_ptr)) {
1098 Py_DECREF(s);
1099 return converterr("(cleanup problem)", arg, msgbuf, bufsize);
1100 }
1101 memcpy(*buffer, ptr, size + 1);
1102 }
1103 Py_DECREF(s);
1104 break;
1105 }
1106
1107 case 'S': { // PyBytes object
1108 PyObject** p = va_arg(*p_va, PyObject**);
1109 if (PyBytes_Check(arg)) {
1110 *p = arg;
1111 } else {
1112 return converterr("bytes", arg, msgbuf, bufsize);
1113 }
1114 break;
1115 }
1116
1117 case 'Y': { // PyByteArray object
1118 PyObject** p = va_arg(*p_va, PyObject**);
1119 if (PyByteArray_Check(arg)) {
1120 *p = arg;
1121 } else {
1122 return converterr("bytearray", arg, msgbuf, bufsize);
1123 }
1124 break;
1125 }
1126
1127 case 'U': { // PyUnicode object
1128 PyObject** p = va_arg(*p_va, PyObject**);
1129 if (PyUnicode_Check(arg)) {
1130 if (PyUnicode_READY(arg) == -1) RETURN_ERR_OCCURRED;
1131 *p = arg;
1132 } else {
1133 return converterr("str", arg, msgbuf, bufsize);
1134 }
1135 break;
1136 }
1137
1138 case 'O': { // object
1139 PyTypeObject* type;
1140 PyObject** p;
1141 if (*format == '!') {
1142 type = va_arg(*p_va, PyTypeObject*);
1143 p = va_arg(*p_va, PyObject**);
1144 format++;
1145 if (PyType_IsSubtype(Py_TYPE(arg), type)) {
1146 *p = arg;
1147 } else {
1148 return converterr(_PyType_Name(type), arg, msgbuf, bufsize);
1149 }
1150
1151 } else if (*format == '&') {
1152 typedef int (*converter)(PyObject*, void*);
1153 converter convert = va_arg(*p_va, converter);
1154 void* addr = va_arg(*p_va, void*);
1155 int res;
1156 format++;
1157 if (!(res = (*convert)(arg, addr))) {
1158 return converterr("(unspecified)", arg, msgbuf, bufsize);
1159 }
1160 if (res == Py_CLEANUP_SUPPORTED &&
1161 addcleanup(addr, freelist, convert) == -1) {
1162 return converterr("(cleanup problem)", arg, msgbuf, bufsize);
1163 }
1164 } else {
1165 p = va_arg(*p_va, PyObject**);
1166 *p = arg;
1167 }
1168 break;
1169 }
1170
1171 case 'w': { // "w*": memory buffer, read-write access
1172 void** p = va_arg(*p_va, void**);
1173
1174 if (*format != '*') {
1175 return converterr("(invalid use of 'w' format character)", arg, msgbuf,
1176 bufsize);
1177 }
1178 format++;
1179
1180 // Caller is interested in Py_buffer, and the object
1181 // supports it directly.
1182 if (PyObject_GetBuffer(arg, reinterpret_cast<Py_buffer*>(p),
1183 PyBUF_WRITABLE) < 0) {
1184 PyErr_Clear();
1185 return converterr("read-write bytes-like object", arg, msgbuf, bufsize);
1186 }
1187 if (!PyBuffer_IsContiguous(reinterpret_cast<Py_buffer*>(p), 'C')) {
1188 PyBuffer_Release(reinterpret_cast<Py_buffer*>(p));
1189 return converterr("contiguous buffer", arg, msgbuf, bufsize);
1190 }
1191 if (addcleanup(p, freelist, cleanup_buffer)) {
1192 return converterr("(cleanup problem)", arg, msgbuf, bufsize);
1193 }
1194 break;
1195 }
1196
1197 default:
1198 return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
1199 }
1200
1201 *p_format = format;
1202 return nullptr;
1203
1204#undef FETCH_SIZE
1205#undef STORE_SIZE
1206#undef BUFFER_LEN
1207#undef RETURN_ERR_OCCURRED
1208}
1209
1210static Py_ssize_t convertbuffer(PyObject* arg, void const** p,
1211 const char** errmsg) {
1212 Py_ssize_t count;
1213 Py_buffer view;
1214
1215 *errmsg = nullptr;
1216 *p = nullptr;
1217 // TODO(miro): check that the bytes-like object is read-only and fail with not
1218 if (getbuffer(arg, &view, errmsg) < 0) return -1;
1219 count = view.len;
1220 *p = view.buf;
1221 PyBuffer_Release(&view);
1222 return count;
1223}
1224
1225static int getbuffer(PyObject* arg, Py_buffer* view, const char** errmsg) {
1226 if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
1227 *errmsg = "bytes-like object";
1228 return -1;
1229 }
1230 if (!PyBuffer_IsContiguous(view, 'C')) {
1231 PyBuffer_Release(view);
1232 *errmsg = "contiguous buffer";
1233 return -1;
1234 }
1235 return 0;
1236}
1237
1238// Support for keyword arguments donated by
1239// Geoff Philbrick <philbric@delphi.hks.com>
1240
1241// Return false (0) for error, else true.
1242PY_EXPORT int PyArg_ParseTupleAndKeywords(PyObject* args, PyObject* keywords,
1243 const char* format, char** kwlist,
1244 ...) {
1245 int retval;
1246 va_list va;
1247
1248 if ((args == nullptr || !PyTuple_Check(args)) ||
1249 (keywords != nullptr && !PyDict_Check(keywords)) || format == nullptr ||
1250 kwlist == nullptr) {
1251 PyErr_BadInternalCall();
1252 return 0;
1253 }
1254
1255 va_start(va, kwlist);
1256 retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
1257 va_end(va);
1258 return retval;
1259}
1260
1261PY_EXPORT int _PyArg_ParseTupleAndKeywords_SizeT(PyObject* args,
1262 PyObject* keywords,
1263 const char* format,
1264 char** kwlist, ...) {
1265 int retval;
1266 va_list va;
1267
1268 if ((args == nullptr || !PyTuple_Check(args)) ||
1269 (keywords != nullptr && !PyDict_Check(keywords)) || format == nullptr ||
1270 kwlist == nullptr) {
1271 PyErr_BadInternalCall();
1272 return 0;
1273 }
1274
1275 va_start(va, kwlist);
1276 retval = vgetargskeywords(args, keywords, format, kwlist, &va, FLAG_SIZE_T);
1277 va_end(va);
1278 return retval;
1279}
1280
1281PY_EXPORT int PyArg_VaParseTupleAndKeywords(PyObject* args, PyObject* keywords,
1282 const char* format, char** kwlist,
1283 va_list va) {
1284 int retval;
1285 va_list lva;
1286
1287 if ((args == nullptr || !PyTuple_Check(args)) ||
1288 (keywords != nullptr && !PyDict_Check(keywords)) || format == nullptr ||
1289 kwlist == nullptr) {
1290 PyErr_BadInternalCall();
1291 return 0;
1292 }
1293
1294 va_copy(lva, va);
1295
1296 retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
1297 va_end(lva);
1298 return retval;
1299}
1300
1301PY_EXPORT int _PyArg_VaParseTupleAndKeywords_SizeT(PyObject* args,
1302 PyObject* keywords,
1303 const char* format,
1304 char** kwlist, va_list va) {
1305 int retval;
1306 va_list lva;
1307
1308 if ((args == nullptr || !PyTuple_Check(args)) ||
1309 (keywords != nullptr && !PyDict_Check(keywords)) || format == nullptr ||
1310 kwlist == nullptr) {
1311 PyErr_BadInternalCall();
1312 return 0;
1313 }
1314
1315 va_copy(lva, va);
1316
1317 retval = vgetargskeywords(args, keywords, format, kwlist, &lva, FLAG_SIZE_T);
1318 va_end(lva);
1319 return retval;
1320}
1321
1322PY_EXPORT int _PyArg_ParseTupleAndKeywordsFast(PyObject* args,
1323 PyObject* keywords,
1324 struct _PyArg_Parser* parser,
1325 ...) {
1326 if ((args == nullptr || !PyTuple_Check(args)) ||
1327 (keywords != nullptr && !PyDict_Check(keywords)) || parser == nullptr) {
1328 PyErr_BadInternalCall();
1329 return 0;
1330 }
1331 va_list va;
1332 va_start(va, parser);
1333 int retval = vGetArgsKeywordsFast(args, keywords, parser, &va, 0);
1334 va_end(va);
1335 return retval;
1336}
1337
1338PY_EXPORT int _PyArg_ParseTupleAndKeywordsFast_SizeT(
1339 PyObject* args, PyObject* keywords, struct _PyArg_Parser* parser, ...) {
1340 if ((args == nullptr || !PyTuple_Check(args)) ||
1341 (keywords != nullptr && !PyDict_Check(keywords)) || parser == nullptr) {
1342 PyErr_BadInternalCall();
1343 return 0;
1344 }
1345
1346 va_list va;
1347 va_start(va, parser);
1348 int retval = vGetArgsKeywordsFast(args, keywords, parser, &va, FLAG_SIZE_T);
1349 va_end(va);
1350 return retval;
1351}
1352
1353PY_EXPORT int _PyArg_ParseStackAndKeywords(PyObject* const* args,
1354 Py_ssize_t nargs, PyObject* kwnames,
1355 struct _PyArg_Parser* parser, ...) {
1356 if ((kwnames != nullptr && !PyTuple_Check(kwnames)) || parser == nullptr) {
1357 PyErr_BadInternalCall();
1358 return 0;
1359 }
1360
1361 va_list va;
1362 va_start(va, parser);
1363 int retval =
1364 vGetArgsKeywordsFastImpl(args, nargs, nullptr, kwnames, parser, &va, 0);
1365 va_end(va);
1366 return retval;
1367}
1368
1369PY_EXPORT int _PyArg_ParseStackAndKeywords_SizeT(PyObject* const* args,
1370 Py_ssize_t nargs,
1371 PyObject* kwnames,
1372 struct _PyArg_Parser* parser,
1373 ...) {
1374 if ((kwnames != nullptr && !PyTuple_Check(kwnames)) || parser == nullptr) {
1375 PyErr_BadInternalCall();
1376 return 0;
1377 }
1378
1379 va_list va;
1380 va_start(va, parser);
1381 int retval = vGetArgsKeywordsFastImpl(args, nargs, nullptr, kwnames, parser,
1382 &va, FLAG_SIZE_T);
1383 va_end(va);
1384 return retval;
1385}
1386
1387#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
1388
1389static bool isValidKeyword(struct _PyArg_Parser* parser,
1390 Py_ssize_t num_keywords, PyObject* key) {
1391 word start = parser->pos;
1392 for (word i = 0; i < num_keywords; i++) {
1393 if (_PyUnicode_EqualToASCIIString(key, parser->keywords[i + start])) {
1394 return true;
1395 }
1396 }
1397 return false;
1398}
1399
1400static int vGetArgsKeywordsFast(PyObject* args, PyObject* keywords,
1401 struct _PyArg_Parser* parser, va_list* p_va,
1402 int flags) {
1403 DCHECK(args != nullptr && PyTuple_Check(args),
1404 "args must be a non-null tuple");
1405 PyObject* small_array[kMaxSmallArraySize];
1406 Py_ssize_t nargs = PyTuple_GET_SIZE(args);
1407 PyObject** stack =
1408 nargs <= kMaxSmallArraySize ? small_array : new PyObject*[nargs];
1409 for (Py_ssize_t i = 0; i < nargs; i++) {
1410 stack[i] = PyTuple_GET_ITEM(args, i);
1411 }
1412 int result = vGetArgsKeywordsFastImpl(stack, nargs, keywords, nullptr, parser,
1413 p_va, flags);
1414 if (stack != small_array) {
1415 delete[] stack;
1416 }
1417 return result;
1418}
1419
1420static int vGetArgsKeywordsFastImpl(PyObject* const* args, Py_ssize_t nargs,
1421 PyObject* keywords, PyObject* kwnames,
1422 struct _PyArg_Parser* parser, va_list* p_va,
1423 int flags) {
1424 freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
1425 freelist_t freelist;
1426 freelist.entries = static_entries;
1427 freelist.first_available = 0;
1428 freelist.entries_malloced = 0;
1429
1430 DCHECK(keywords == nullptr || PyDict_Check(keywords),
1431 "keywords must be null or a dict");
1432 DCHECK(kwnames == nullptr || PyTuple_Check(kwnames),
1433 "kwnames must be null or a tuple");
1434 DCHECK(keywords == nullptr || kwnames == nullptr,
1435 "both keywords and kwnames cannot be non-null");
1436 DCHECK(parser != nullptr, "parser must not be null");
1437 DCHECK(p_va != nullptr, "p_va must not be null");
1438
1439 int keyword_count = 0;
1440 if (!parserInit(parser, &keyword_count)) {
1441 return false;
1442 }
1443
1444 int pos = parser->pos;
1445 int len = pos + keyword_count;
1446
1447 if (len > STATIC_FREELIST_ENTRIES) {
1448 freelist.entries = PyMem_NEW(freelistentry_t, len);
1449 if (freelist.entries == nullptr) {
1450 PyErr_NoMemory();
1451 return 0;
1452 }
1453 freelist.entries_malloced = 1;
1454 }
1455
1456 Py_ssize_t num_keywords = 0;
1457 PyObject* const* kwstack = nullptr;
1458 if (keywords != nullptr) {
1459 num_keywords = PyDict_Size(keywords);
1460 } else if (kwnames != nullptr) {
1461 num_keywords = PyTuple_GET_SIZE(kwnames);
1462 kwstack = args + nargs;
1463 }
1464
1465 if (nargs + num_keywords > len) {
1466 PyErr_Format(PyExc_TypeError,
1467 "%s%s takes at most %d argument%s (%zd given)",
1468 (parser->fname == nullptr) ? "function" : parser->fname,
1469 (parser->fname == nullptr) ? "" : "()", len,
1470 (len == 1) ? "" : "s", nargs + num_keywords);
1471 return cleanreturn(0, &freelist);
1472 }
1473 if (parser->max < nargs) {
1474 PyErr_Format(
1475 PyExc_TypeError, "Function takes %s %d positional arguments (%d given)",
1476 (parser->min != INT_MAX) ? "at most" : "exactly", parser->max, nargs);
1477 return cleanreturn(0, &freelist);
1478 }
1479
1480 // convert tuple args and keyword args in same loop, using kwtuple to drive
1481 // process
1482 const char* format = parser->format;
1483 for (int i = 0; i < len; i++) {
1484 const char* keyword = i >= pos ? parser->keywords[i] : nullptr;
1485 if (*format == '|') {
1486 format++;
1487 }
1488 if (*format == '$') {
1489 format++;
1490 }
1491 DCHECK(!IS_END_OF_FORMAT(*format), "end of format was reached");
1492
1493 PyObject* current_arg = nullptr;
1494 if (num_keywords && i >= pos) {
1495 if (keywords != nullptr) {
1496 current_arg = PyDict_GetItemString(keywords, keyword);
1497 if (current_arg == nullptr && PyErr_Occurred()) {
1498 return cleanreturn(0, &freelist);
1499 }
1500 } else {
1501 current_arg = findKeyword(kwnames, kwstack, keyword);
1502 }
1503 }
1504 if (current_arg != nullptr) {
1505 --num_keywords;
1506 if (i < nargs) {
1507 // arg present in tuple and in dict
1508 PyErr_Format(PyExc_TypeError,
1509 "Argument given by name ('%s') "
1510 "and position (%d)",
1511 keyword, i + 1);
1512 return cleanreturn(0, &freelist);
1513 }
1514 } else if (i < nargs) {
1515 current_arg = args[i];
1516 }
1517
1518 if (current_arg != nullptr) {
1519 char msgbuf[512];
1520 int levels[32];
1521 const char* msg = convertitem(current_arg, &format, p_va, flags, levels,
1522 msgbuf, sizeof(msgbuf), &freelist);
1523 if (msg) {
1524 seterror(i + 1, msg, levels, parser->fname, parser->custom_msg);
1525 return cleanreturn(0, &freelist);
1526 }
1527 continue;
1528 }
1529
1530 if (i < parser->min) {
1531 // Less arguments than required
1532 if (i < pos) {
1533 PyErr_Format(
1534 PyExc_TypeError,
1535 "Function takes %s %d positional arguments"
1536 " (%d given)",
1537 (Py_MIN(pos, parser->min) < parser->max) ? "at least" : "exactly",
1538 Py_MIN(pos, parser->min), nargs);
1539 } else {
1540 PyErr_Format(PyExc_TypeError,
1541 "Required argument "
1542 "'%s' (pos %d) not found",
1543 keyword, i + 1);
1544 }
1545 return cleanreturn(0, &freelist);
1546 }
1547 // current code reports success when all required args fulfilled and no
1548 // keyword args left, with no further validation.
1549 if (!num_keywords) {
1550 return cleanreturn(1, &freelist);
1551 }
1552
1553 // We are into optional args, skip through to any remaining keyword args
1554 const char* message = skipitem(&format, p_va, flags);
1555 DCHECK(message == nullptr, "message was not null");
1556 }
1557
1558 DCHECK(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$'),
1559 "expected end of format, '|', '$'");
1560
1561 // make sure there are no extraneous keyword arguments
1562 if (num_keywords > 0) {
1563 if (keywords != nullptr) {
1564 PyObject *key, *value;
1565 Py_ssize_t pos1 = 0;
1566 while (PyDict_Next(keywords, &pos1, &key, &value)) {
1567 if (!PyUnicode_Check(key)) {
1568 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
1569 "keywords must be strings");
1570 return cleanreturn(0, &freelist);
1571 }
1572 if (!isValidKeyword(parser, keyword_count, key)) {
1573 PyErr_Format(PyExc_TypeError,
1574 "'%s' is an invalid keyword "
1575 "argument for this function",
1576 key);
1577 return cleanreturn(0, &freelist);
1578 }
1579 }
1580 } else {
1581 Py_ssize_t num_kwargs = PyTuple_GET_SIZE(kwnames);
1582 for (Py_ssize_t j = 0; j < num_kwargs; j++) {
1583 PyObject* key = PyTuple_GET_ITEM(kwnames, j);
1584 if (!PyUnicode_Check(key)) {
1585 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
1586 "keywords must be strings");
1587 return cleanreturn(0, &freelist);
1588 }
1589 if (!isValidKeyword(parser, keyword_count, key)) {
1590 PyErr_Format(PyExc_TypeError,
1591 "'%U' is an invalid keyword "
1592 "argument for this function",
1593 key);
1594 return cleanreturn(0, &freelist);
1595 }
1596 }
1597 }
1598 }
1599 return cleanreturn(1, &freelist);
1600}
1601
1602static int vgetargskeywords(PyObject* args, PyObject* keywords,
1603 const char* format, char** kwlist, va_list* p_va,
1604 int flags) {
1605 char msgbuf[512];
1606 int levels[32];
1607 const char *fname, *msg, *custom_msg, *keyword;
1608 int min = INT_MAX;
1609 int max = INT_MAX;
1610 int i, pos, len;
1611 int skip = 0;
1612 Py_ssize_t nargs, nkeywords;
1613 PyObject* current_arg;
1614 freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
1615 freelist_t freelist;
1616
1617 freelist.entries = static_entries;
1618 freelist.first_available = 0;
1619 freelist.entries_malloced = 0;
1620
1621 assert(args != nullptr && PyTuple_Check(args));
1622 assert(keywords == nullptr || PyDict_Check(keywords));
1623 assert(format != nullptr);
1624 assert(kwlist != nullptr);
1625 assert(p_va != nullptr);
1626
1627 // grab the function name or custom error msg first (mutually exclusive)
1628 fname = strchr(format, ':');
1629 if (fname) {
1630 fname++;
1631 custom_msg = nullptr;
1632 } else {
1633 custom_msg = strchr(format, ';');
1634 if (custom_msg) custom_msg++;
1635 }
1636
1637 // scan kwlist and count the number of positional-only parameters
1638 for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) {
1639 }
1640 // scan kwlist and get greatest possible nbr of args
1641 for (len = pos; kwlist[len]; len++) {
1642 if (!*kwlist[len]) {
1643 Thread::current()->raiseWithFmt(LayoutId::kSystemError,
1644 "Empty keyword parameter name");
1645 return cleanreturn(0, &freelist);
1646 }
1647 }
1648
1649 if (len > STATIC_FREELIST_ENTRIES) {
1650 freelist.entries = PyMem_NEW(freelistentry_t, len);
1651 if (freelist.entries == nullptr) {
1652 PyErr_NoMemory();
1653 return 0;
1654 }
1655 freelist.entries_malloced = 1;
1656 }
1657
1658 nargs = PyTuple_GET_SIZE(args);
1659 nkeywords = (keywords == nullptr) ? 0 : PyDict_Size(keywords);
1660 if (nargs + nkeywords > len) {
1661 PyErr_Format(
1662 PyExc_TypeError, "%s%s takes at most %d argument%s (%zd given)",
1663 (fname == nullptr) ? "function" : fname, (fname == nullptr) ? "" : "()",
1664 len, (len == 1) ? "" : "s", nargs + nkeywords);
1665 return cleanreturn(0, &freelist);
1666 }
1667
1668 // convert tuple args and keyword args in same loop, using kwlist to drive
1669 // process
1670 for (i = 0; i < len; i++) {
1671 keyword = kwlist[i];
1672 if (*format == '|') {
1673 if (min != INT_MAX) {
1674 Thread::current()->raiseWithFmt(
1675 LayoutId::kSystemError,
1676 "Invalid format string (| specified twice)");
1677 return cleanreturn(0, &freelist);
1678 }
1679
1680 min = i;
1681 format++;
1682
1683 if (max != INT_MAX) {
1684 Thread::current()->raiseWithFmt(LayoutId::kSystemError,
1685 "Invalid format string ($ before |)");
1686 return cleanreturn(0, &freelist);
1687 }
1688 }
1689 if (*format == '$') {
1690 if (max != INT_MAX) {
1691 Thread::current()->raiseWithFmt(
1692 LayoutId::kSystemError,
1693 "Invalid format string ($ specified twice)");
1694 return cleanreturn(0, &freelist);
1695 }
1696
1697 max = i;
1698 format++;
1699
1700 if (max < pos) {
1701 Thread::current()->raiseWithFmt(LayoutId::kSystemError,
1702 "Empty parameter name after $");
1703 return cleanreturn(0, &freelist);
1704 }
1705 if (skip) {
1706 // Now we know the minimal and the maximal numbers of
1707 // positional arguments and can raise an exception with
1708 // informative message (see below).
1709 break;
1710 }
1711 if (max < nargs) {
1712 PyErr_Format(PyExc_TypeError,
1713 "Function takes %s %d positional arguments"
1714 " (%d given)",
1715 (min != INT_MAX) ? "at most" : "exactly", max, nargs);
1716 return cleanreturn(0, &freelist);
1717 }
1718 }
1719 if (IS_END_OF_FORMAT(*format)) {
1720 PyErr_Format(PyExc_SystemError,
1721 "More keyword list entries (%d) than "
1722 "format specifiers (%d)",
1723 len, i);
1724 return cleanreturn(0, &freelist);
1725 }
1726 if (!skip) {
1727 current_arg = nullptr;
1728 if (nkeywords && i >= pos) {
1729 current_arg = PyDict_GetItemString(keywords, keyword);
1730 if (!current_arg && PyErr_Occurred()) {
1731 return cleanreturn(0, &freelist);
1732 }
1733 }
1734 if (current_arg) {
1735 --nkeywords;
1736 if (i < nargs) {
1737 // arg present in tuple and in dict
1738 PyErr_Format(PyExc_TypeError,
1739 "Argument given by name ('%s') "
1740 "and position (%d)",
1741 keyword, i + 1);
1742 return cleanreturn(0, &freelist);
1743 }
1744 } else if (i < nargs) {
1745 // Facebook: Use PyTuple_GetItem instead of &PyTuple_GET_ITEM
1746 // (D12953145)
1747 current_arg = PyTuple_GetItem(args, i);
1748 }
1749
1750 if (current_arg) {
1751 msg = convertitem(current_arg, &format, p_va, flags, levels, msgbuf,
1752 sizeof(msgbuf), &freelist);
1753 if (msg) {
1754 seterror(i + 1, msg, levels, fname, custom_msg);
1755 return cleanreturn(0, &freelist);
1756 }
1757 continue;
1758 }
1759
1760 if (i < min) {
1761 if (i < pos) {
1762 assert(min == INT_MAX);
1763 assert(max == INT_MAX);
1764 skip = 1;
1765 // At that moment we still don't know the minimal and
1766 // the maximal numbers of positional arguments. Raising
1767 // an exception is deferred until we encounter | and $
1768 // or the end of the format.
1769 } else {
1770 PyErr_Format(PyExc_TypeError,
1771 "Required argument "
1772 "'%s' (pos %d) not found",
1773 keyword, i + 1);
1774 return cleanreturn(0, &freelist);
1775 }
1776 }
1777 // current code reports success when all required args
1778 // fulfilled and no keyword args left, with no further
1779 // validation. XXX Maybe skip this in debug build ?
1780
1781 if (!nkeywords && !skip) {
1782 return cleanreturn(1, &freelist);
1783 }
1784 }
1785
1786 // We are into optional args, skip thru to any remaining
1787 // keyword args
1788 msg = skipitem(&format, p_va, flags);
1789 if (msg) {
1790 PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, format);
1791 return cleanreturn(0, &freelist);
1792 }
1793 }
1794
1795 if (skip) {
1796 PyErr_Format(PyExc_TypeError,
1797 "Function takes %s %d positional arguments"
1798 " (%d given)",
1799 (Py_MIN(pos, min) < i) ? "at least" : "exactly",
1800 Py_MIN(pos, min), nargs);
1801 return cleanreturn(0, &freelist);
1802 }
1803
1804 if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
1805 PyErr_Format(PyExc_SystemError,
1806 "more argument specifiers than keyword list entries "
1807 "(remaining format:'%s')",
1808 format);
1809 return cleanreturn(0, &freelist);
1810 }
1811
1812 // make sure there are no extraneous keyword arguments
1813 if (nkeywords > 0) {
1814 PyObject *key, *value;
1815 Py_ssize_t iter_pos = 0;
1816 while (PyDict_Next(keywords, &iter_pos, &key, &value)) {
1817 int match = 0;
1818 if (!PyUnicode_Check(key)) {
1819 Thread::current()->raiseWithFmt(LayoutId::kTypeError,
1820 "keywords must be strings");
1821 return cleanreturn(0, &freelist);
1822 }
1823 for (i = 0; i < len; i++) {
1824 if (*kwlist[i] && _PyUnicode_EqualToASCIIString(key, kwlist[i])) {
1825 match = 1;
1826 break;
1827 }
1828 }
1829 if (!match) {
1830 PyErr_Format(PyExc_TypeError,
1831 "'%U' is an invalid keyword "
1832 "argument for this function",
1833 key);
1834 return cleanreturn(0, &freelist);
1835 }
1836 }
1837 }
1838
1839 return cleanreturn(1, &freelist);
1840}
1841
1842static bool parserInit(struct _PyArg_Parser* parser, int* keyword_count) {
1843 DCHECK(parser->keywords != nullptr, "parser->keywords must not be null");
1844
1845 // grab the function name or custom error msg first (mutually exclusive)
1846 const char* format = parser->format;
1847 if (format != nullptr) {
1848 parser->fname = std::strchr(format, ':');
1849 if (parser->fname != nullptr) {
1850 parser->fname++;
1851 parser->custom_msg = nullptr;
1852 } else {
1853 parser->custom_msg = std::strchr(format, ';');
1854 if (parser->custom_msg) parser->custom_msg++;
1855 }
1856 }
1857
1858 const char* const* keywords = parser->keywords;
1859 // scan keywords and count the number of positional-only parameters
1860 parser->pos = 0;
1861 for (int i = 0; keywords[i] != nullptr && !*keywords[i]; i++) {
1862 parser->pos++;
1863 }
1864
1865 // scan keywords and get greatest possible nbr of args
1866 int len = parser->pos;
1867 for (; keywords[len] != nullptr; len++) {
1868 if (*keywords[len] == '\0') {
1869 Thread::current()->raiseWithFmt(LayoutId::kSystemError,
1870 "Empty keyword parameter name");
1871 return false;
1872 }
1873 }
1874
1875 if (format != nullptr) {
1876 int min, max;
1877 min = max = INT_MAX;
1878 for (int i = 0; i < len; i++) {
1879 if (*format == '|') {
1880 if (min != INT_MAX) {
1881 Thread::current()->raiseWithFmt(
1882 LayoutId::kSystemError,
1883 "Invalid format string (| specified twice)");
1884 return false;
1885 }
1886 if (max != INT_MAX) {
1887 Thread::current()->raiseWithFmt(LayoutId::kSystemError,
1888 "Invalid format string ($ before |)");
1889 return false;
1890 }
1891 min = i;
1892 format++;
1893 }
1894 if (*format == '$') {
1895 if (max != INT_MAX) {
1896 Thread::current()->raiseWithFmt(
1897 LayoutId::kSystemError,
1898 "Invalid format string ($ specified twice)");
1899 return false;
1900 }
1901 if (i < parser->pos) {
1902 Thread::current()->raiseWithFmt(LayoutId::kSystemError,
1903 "Empty parameter name after $");
1904 return false;
1905 }
1906 max = i;
1907 format++;
1908 }
1909 if (IS_END_OF_FORMAT(*format)) {
1910 PyErr_Format(PyExc_SystemError,
1911 "More keyword list entries (%d) than "
1912 "format specifiers (%d)",
1913 len, i);
1914 return false;
1915 }
1916
1917 const char* msg;
1918 msg = skipitem(&format, nullptr, 0);
1919 if (msg) {
1920 PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, format);
1921 return false;
1922 }
1923 }
1924 parser->min = Py_MIN(min, len);
1925 parser->max = Py_MIN(max, len);
1926
1927 if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
1928 PyErr_Format(PyExc_SystemError,
1929 "more argument specifiers than keyword list entries "
1930 "(remaining format:'%s')",
1931 format);
1932 return false;
1933 }
1934 }
1935
1936 *keyword_count = len - parser->pos;
1937 return true;
1938}
1939
1940static PyObject* findKeyword(PyObject* kwnames, PyObject* const* kwstack,
1941 const char* key) {
1942 Py_ssize_t num_kwargs = PyTuple_GET_SIZE(kwnames);
1943 for (Py_ssize_t i = 0; i < num_kwargs; i++) {
1944 PyObject* kwname = PyTuple_GET_ITEM(kwnames, i);
1945
1946 if (!PyUnicode_Check(kwname)) {
1947 // ignore non-string keyword keys: an error will be raised above
1948 continue;
1949 }
1950 if (_PyUnicode_EqualToASCIIString(kwname, key)) {
1951 return kwstack[i];
1952 }
1953 }
1954 return nullptr;
1955}
1956
1957static const char* skipitem(const char** p_format, va_list* p_va, int flags) {
1958 const char* format = *p_format;
1959 char c = *format++;
1960
1961 switch (c) {
1962 // codes that take a single data pointer as an argument
1963 // (the type of the pointer is irrelevant)
1964 case 'b': // byte -- very short int
1965 case 'B': // byte as bitfield
1966 case 'h': // short int
1967 case 'H': // short int as bitfield
1968 case 'i': // int
1969 case 'I': // int sized bitfield
1970 case 'l': // long int
1971 case 'k': // long int sized bitfield
1972 case 'L': // long long
1973 case 'K': // long long sized bitfield
1974 case 'n': // Py_ssize_t
1975 case 'f': // float
1976 case 'd': // double
1977 case 'D': // complex double
1978 case 'c': // char
1979 case 'C': // unicode char
1980 case 'p': // boolean predicate
1981 case 'S': // string object
1982 case 'Y': // string object
1983 case 'U': // unicode string object
1984 {
1985 if (p_va != nullptr) {
1986 (void)va_arg(*p_va, void*);
1987 }
1988 break;
1989 }
1990
1991 // string codes
1992 case 'e': // string with encoding
1993 {
1994 if (p_va != nullptr) {
1995 va_arg(*p_va, const char*);
1996 }
1997 if (!(*format == 's' ||
1998 *format == 't')) { // after 'e', only 's' and 't' is allowed
1999 goto err;
2000 }
2001 format++;
2002 }
2003 // fall through
2004
2005 case 's': // string
2006 case 'z': // string or None
2007 case 'y': // bytes
2008 case 'u': // unicode string
2009 case 'Z': // unicode string or None
2010 case 'w': // buffer, read-write
2011 {
2012 if (p_va != nullptr) {
2013 (void)va_arg(*p_va, char**);
2014 }
2015 if (*format == '#') {
2016 if (p_va != nullptr) {
2017 if (flags & FLAG_SIZE_T) {
2018 va_arg(*p_va, Py_ssize_t*);
2019 } else {
2020 va_arg(*p_va, int*);
2021 }
2022 }
2023 format++;
2024 } else if ((c == 's' || c == 'z' || c == 'y') && *format == '*') {
2025 format++;
2026 }
2027 break;
2028 }
2029
2030 case 'O': // object
2031 {
2032 if (*format == '!') {
2033 format++;
2034 if (p_va != nullptr) {
2035 va_arg(*p_va, PyTypeObject*);
2036 va_arg(*p_va, PyObject**);
2037 }
2038 } else if (*format == '&') {
2039 typedef int (*converter)(PyObject*, void*);
2040 if (p_va != nullptr) {
2041 va_arg(*p_va, converter);
2042 va_arg(*p_va, void*);
2043 }
2044 format++;
2045 } else {
2046 if (p_va != nullptr) {
2047 va_arg(*p_va, PyObject**);
2048 }
2049 }
2050 break;
2051 }
2052
2053 case '(': // bypass tuple, not handled at all previously
2054 {
2055 const char* msg;
2056 for (;;) {
2057 if (*format == ')') break;
2058 if (IS_END_OF_FORMAT(*format)) {
2059 return "Unmatched left paren in format "
2060 "string";
2061 }
2062 msg = skipitem(&format, p_va, flags);
2063 if (msg) return msg;
2064 }
2065 format++;
2066 break;
2067 }
2068
2069 case ')':
2070 return "Unmatched right paren in format string";
2071
2072 default:
2073 err:
2074 return "impossible<bad format char>";
2075 }
2076
2077 *p_format = format;
2078 return nullptr;
2079}
2080
2081PY_EXPORT int PyArg_UnpackTuple(PyObject* args, const char* name,
2082 Py_ssize_t min, Py_ssize_t max, ...) {
2083 Py_ssize_t i, l;
2084 PyObject** o;
2085 va_list vargs;
2086
2087 assert(min >= 0);
2088 assert(min <= max);
2089 if (!PyTuple_Check(args)) {
2090 Thread::current()->raiseWithFmt(
2091 LayoutId::kSystemError,
2092 "PyArg_UnpackTuple() argument list is not a tuple");
2093 return 0;
2094 }
2095 l = PyTuple_GET_SIZE(args);
2096 if (l < min) {
2097 if (name != nullptr) {
2098 PyErr_Format(PyExc_TypeError, "%s expected %s%zd arguments, got %zd",
2099 name, (min == max ? "" : "at least "), min, l);
2100 } else {
2101 PyErr_Format(PyExc_TypeError,
2102 "unpacked tuple should have %s%zd elements,"
2103 " but has %zd",
2104 (min == max ? "" : "at least "), min, l);
2105 }
2106 return 0;
2107 }
2108 if (l == 0) return 1;
2109 if (l > max) {
2110 if (name != nullptr) {
2111 PyErr_Format(PyExc_TypeError, "%s expected %s%zd arguments, got %zd",
2112 name, (min == max ? "" : "at most "), max, l);
2113 } else {
2114 PyErr_Format(PyExc_TypeError,
2115 "unpacked tuple should have %s%zd elements,"
2116 " but has %zd",
2117 (min == max ? "" : "at most "), max, l);
2118 }
2119 return 0;
2120 }
2121
2122 va_start(vargs, max);
2123 for (i = 0; i < l; i++) {
2124 o = va_arg(vargs, PyObject**);
2125 // Facebook: Use PyTuple_GetItem instead of &PyTuple_GET_ITEM (D12953145)
2126 *o = PyTuple_GetItem(args, i);
2127 }
2128 va_end(vargs);
2129 return 1;
2130}
2131
2132PY_EXPORT void _PyArg_BadArgument(const char* fname, const char* displayname,
2133 const char* expected, PyObject* arg) {
2134 PyErr_Format(PyExc_TypeError, "%.200s() %.200s must be %.50s, not %.50s",
2135 fname, displayname, expected,
2136 arg == Py_None ? "None" : _PyType_Name(Py_TYPE(arg)));
2137}
2138
2139PY_EXPORT int _PyArg_CheckPositional(const char* name, Py_ssize_t nargs,
2140 Py_ssize_t min, Py_ssize_t max) {
2141 DCHECK_BOUND(min, max);
2142
2143 if (nargs < min) {
2144 if (name != nullptr) {
2145 PyErr_Format(PyExc_TypeError, "%.200s expected %s%zd argument%s, got %zd",
2146 name, (min == max ? "" : "at least "), min,
2147 min == 1 ? "" : "s", nargs);
2148 } else {
2149 PyErr_Format(PyExc_TypeError,
2150 "unpacked tuple should have %s%zd element%s,"
2151 " but has %zd",
2152 (min == max ? "" : "at least "), min, min == 1 ? "" : "s",
2153 nargs);
2154 }
2155 return 0;
2156 }
2157
2158 if (nargs > max) {
2159 if (name != nullptr) {
2160 PyErr_Format(PyExc_TypeError, "%.200s expected %s%zd argument%s, got %zd",
2161 name, (min == max ? "" : "at most "), max,
2162 max == 1 ? "" : "s", nargs);
2163 } else {
2164 PyErr_Format(PyExc_TypeError,
2165 "unpacked tuple should have %s%zd element%s,"
2166 " but has %zd",
2167 (min == max ? "" : "at most "), max, max == 1 ? "" : "s",
2168 nargs);
2169 }
2170 return 0;
2171 }
2172
2173 return 1;
2174}
2175
2176static int unpackStack(PyObject* const* args, Py_ssize_t nargs,
2177 const char* name, Py_ssize_t min, Py_ssize_t max,
2178 va_list vargs) {
2179 DCHECK(min >= 0, "min must be positive");
2180 DCHECK(min <= max, "min must be <= max");
2181
2182 if (nargs < min) {
2183 if (name != nullptr) {
2184 PyErr_Format(PyExc_TypeError, "%.200s expected %s%zd arguments, got %zd",
2185 name, (min == max ? "" : "at least "), min, nargs);
2186 } else {
2187 PyErr_Format(PyExc_TypeError,
2188 "unpacked tuple should have %s%zd elements,"
2189 " but has %zd",
2190 (min == max ? "" : "at least "), min, nargs);
2191 }
2192 return 0;
2193 }
2194
2195 if (nargs == 0) {
2196 return 1;
2197 }
2198
2199 if (nargs > max) {
2200 if (name != nullptr) {
2201 PyErr_Format(PyExc_TypeError, "%.200s expected %s%zd arguments, got %zd",
2202 name, (min == max ? "" : "at most "), max, nargs);
2203 } else {
2204 PyErr_Format(PyExc_TypeError,
2205 "unpacked tuple should have %s%zd elements,"
2206 " but has %zd",
2207 (min == max ? "" : "at most "), max, nargs);
2208 }
2209 return 0;
2210 }
2211
2212 for (Py_ssize_t i = 0; i < nargs; i++) {
2213 PyObject** o = va_arg(vargs, PyObject**);
2214 *o = args[i];
2215 }
2216 return 1;
2217}
2218
2219PY_EXPORT int _PyArg_UnpackStack(PyObject* const* args, Py_ssize_t nargs,
2220 const char* name, Py_ssize_t min,
2221 Py_ssize_t max, ...) {
2222 va_list vargs;
2223 va_start(vargs, max);
2224 int retval = unpackStack(args, nargs, name, min, max, vargs);
2225 va_end(vargs);
2226 return retval;
2227}
2228
2229PY_EXPORT int _PyArg_NoKeywords(const char* funcname, PyObject* kwargs) {
2230 if (kwargs == nullptr) {
2231 return 1;
2232 }
2233 if (!PyDict_CheckExact(kwargs)) {
2234 PyErr_BadInternalCall();
2235 return 0;
2236 }
2237 if (PyDict_Size(kwargs) == 0) {
2238 return 1;
2239 }
2240 PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
2241 funcname);
2242 return 0;
2243}
2244
2245PY_EXPORT int _PyArg_NoPositional(const char* funcname, PyObject* args) {
2246 if (args == nullptr) {
2247 return 1;
2248 }
2249 if (!PyTuple_CheckExact(args)) {
2250 PyErr_BadInternalCall();
2251 return 0;
2252 }
2253 if (PyTuple_Size(args) == 0) {
2254 return 1;
2255 }
2256 PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments",
2257 funcname);
2258 return 0;
2259}
2260
2261PY_EXPORT PyObject* const* _PyArg_UnpackKeywords(
2262 PyObject* const* args, Py_ssize_t nargs, PyObject* kwargs,
2263 PyObject* kwnames, struct _PyArg_Parser* parser, int minpos, int maxpos,
2264 int minkw, PyObject** buf) {
2265 DCHECK(kwargs == nullptr || PyDict_Check(kwargs),
2266 "kwargs must be dict or NULL");
2267 DCHECK(kwargs == nullptr || kwnames == nullptr,
2268 "cannot have both kwargs and kwnames");
2269
2270 if (parser == nullptr) {
2271 PyErr_BadInternalCall();
2272 return nullptr;
2273 }
2274
2275 if (kwnames != nullptr && !PyTuple_Check(kwnames)) {
2276 PyErr_BadInternalCall();
2277 return nullptr;
2278 }
2279
2280 if (args == nullptr && nargs == 0) {
2281 args = buf;
2282 }
2283
2284 int keyword_count = 0;
2285 if (!parserInit(parser, &keyword_count)) {
2286 return nullptr;
2287 }
2288
2289 PyObject* kwtuple = parser->kwtuple;
2290 int posonly = parser->pos;
2291 int minposonly = Py_MIN(posonly, minpos);
2292 int maxargs = posonly + keyword_count;
2293
2294 Py_ssize_t nkwargs;
2295 PyObject* const* kwstack = nullptr;
2296 if (kwargs != nullptr) {
2297 nkwargs = PyDict_GET_SIZE(kwargs);
2298 } else if (kwnames != nullptr) {
2299 nkwargs = PyTuple_GET_SIZE(kwnames);
2300 kwstack = args + nargs;
2301 } else {
2302 nkwargs = 0;
2303 }
2304
2305 if (nkwargs == 0 && minkw == 0 && minpos <= nargs && nargs <= maxpos) {
2306 /* Fast path. */
2307 return args;
2308 }
2309
2310 if (nargs + nkwargs > maxargs) {
2311 /* Adding "keyword" (when nargs == 0) prevents producing wrong error
2312 messages in some special cases (see bpo-31229). */
2313 PyErr_Format(PyExc_TypeError,
2314 "%.200s%s takes at most %d %sargument%s (%zd given)",
2315 (parser->fname == nullptr) ? "function" : parser->fname,
2316 (parser->fname == nullptr) ? "" : "()", maxargs,
2317 (nargs == 0) ? "keyword " : "", (maxargs == 1) ? "" : "s",
2318 nargs + nkwargs);
2319 return nullptr;
2320 }
2321
2322 if (nargs > maxpos) {
2323 if (maxpos == 0) {
2324 PyErr_Format(PyExc_TypeError, "%.200s%s takes no positional arguments",
2325 (parser->fname == nullptr) ? "function" : parser->fname,
2326 (parser->fname == nullptr) ? "" : "()");
2327 } else {
2328 PyErr_Format(PyExc_TypeError,
2329 "%.200s%s takes %s %d positional argument%s (%zd given)",
2330 (parser->fname == nullptr) ? "function" : parser->fname,
2331 (parser->fname == nullptr) ? "" : "()",
2332 (minpos < maxpos) ? "at most" : "exactly", maxpos,
2333 (maxpos == 1) ? "" : "s", nargs);
2334 }
2335 return nullptr;
2336 }
2337
2338 if (nargs < minposonly) {
2339 PyErr_Format(PyExc_TypeError,
2340 "%.200s%s takes %s %d positional argument%s"
2341 " (%zd given)",
2342 (parser->fname == nullptr) ? "function" : parser->fname,
2343 (parser->fname == nullptr) ? "" : "()",
2344 minposonly < maxpos ? "at least" : "exactly", minposonly,
2345 minposonly == 1 ? "" : "s", nargs);
2346 return nullptr;
2347 }
2348
2349 /* copy tuple args */
2350 for (Py_ssize_t i = 0; i < nargs; i++) {
2351 buf[i] = args[i];
2352 }
2353
2354 /* copy keyword args using kwtuple to drive process */
2355 int reqlimit = minkw ? maxpos + minkw : minpos;
2356 for (int i = Py_MAX(nargs, posonly); i < maxargs; i++) {
2357 PyObject* current_arg;
2358 if (nkwargs) {
2359 const char* keyword = i >= posonly ? parser->keywords[i] : nullptr;
2360 if (kwargs != nullptr) {
2361 current_arg = PyDict_GetItemString(kwargs, keyword);
2362 if (!current_arg && PyErr_Occurred()) {
2363 return nullptr;
2364 }
2365 } else {
2366 current_arg = findKeyword(kwnames, kwstack, keyword);
2367 }
2368 } else if (i >= reqlimit) {
2369 break;
2370 } else {
2371 current_arg = nullptr;
2372 }
2373
2374 buf[i] = current_arg;
2375
2376 if (current_arg != nullptr) {
2377 --nkwargs;
2378 } else if (i < minpos || (maxpos <= i && i < reqlimit)) {
2379 /* Less arguments than required */
2380 const char* keyword = i >= posonly ? parser->keywords[i] : nullptr;
2381 PyErr_Format(PyExc_TypeError,
2382 "%.200s%s missing required "
2383 "argument '%s' (pos %d)",
2384 (parser->fname == nullptr) ? "function" : parser->fname,
2385 (parser->fname == nullptr) ? "" : "()", keyword, i + 1);
2386 return nullptr;
2387 }
2388 }
2389
2390 if (nkwargs > 0) {
2391 // make sure there are no arguments given by name and position
2392 for (int i = posonly; i < nargs; i++) {
2393 PyObject* current_arg;
2394 const char* keyword = i >= posonly ? parser->keywords[i] : nullptr;
2395 if (kwargs != nullptr) {
2396 current_arg = PyDict_GetItemString(kwargs, keyword);
2397 if (!current_arg && PyErr_Occurred()) {
2398 return nullptr;
2399 }
2400 } else {
2401 current_arg = findKeyword(kwnames, kwstack, keyword);
2402 }
2403
2404 if (current_arg != nullptr) {
2405 // arg present in tuple and in dict
2406 PyErr_Format(PyExc_TypeError,
2407 "argument for %.200s%s given by name ('%s') "
2408 "and position (%d)",
2409 (parser->fname == nullptr) ? "function" : parser->fname,
2410 (parser->fname == nullptr) ? "" : "()", keyword, i + 1);
2411 return nullptr;
2412 }
2413 }
2414
2415 // make sure there are no extraneous keyword arguments
2416 Py_ssize_t j = 0;
2417 for (;;) {
2418 int match;
2419 PyObject* kw;
2420 if (kwargs != nullptr) {
2421 if (!PyDict_Next(kwargs, &j, &kw, nullptr)) break;
2422 } else {
2423 if (j >= PyTuple_GET_SIZE(kwnames)) break;
2424 kw = PyTuple_GET_ITEM(kwnames, j);
2425 j++;
2426 }
2427
2428 if (!PyUnicode_Check(kw)) {
2429 PyErr_SetString(PyExc_TypeError, "keywords must be strings");
2430 return nullptr;
2431 }
2432
2433 match = PySequence_Contains(kwtuple, kw);
2434 if (match <= 0) {
2435 if (!match) {
2436 PyErr_Format(
2437 PyExc_TypeError,
2438 "'%U' is an invalid keyword "
2439 "argument for %.200s%s",
2440 kw, (parser->fname == nullptr) ? "this function" : parser->fname,
2441 (parser->fname == nullptr) ? "" : "()");
2442 }
2443 return nullptr;
2444 }
2445 }
2446 }
2447
2448 return buf;
2449}
2450
2451PY_EXPORT int PyArg_ValidateKeywordArguments(PyObject*) {
2452 UNIMPLEMENTED("PyArg_ValidateKeywordArguments");
2453}
2454
2455// Adding empty function to be compatible with cpython
2456PY_EXPORT void _PyArg_Fini(void) { return; }
2457
2458} // namespace py