Py_DECREF(s); return converterr( "(cleanup problem)", arg, msgbuf, bufsize); } } else { if (size + 1 > BUFFER_LEN) { Py_DECREF(s); return converterr( "(buffer overflow)", arg, msgbuf, bufsize); } } memcpy(*buffer, PyString_AS_STRING(s), size + 1); STORE_SIZE(size); } else { /* Using a 0-terminated buffer: - the encoded string has to be 0-terminated for this variant to work; if it is not, an error raised - a new buffer of the needed size is allocated and the data copied into it; *buffer is updated to point to the new buffer; the caller is responsible for PyMem_Free()ing it after usage */ if ((Py_ssize_t)strlen(PyString_AS_STRING(s)) != size) { Py_DECREF(s); return converterr( "(encoded string without NULL bytes)", arg, msgbuf, bufsize); } *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); return converterr("(memory error)", arg, msgbuf, bufsize); } if(addcleanup(*buffer, freelist)) { Py_DECREF(s); return converterr("(cleanup problem)", arg, msgbuf, bufsize); } memcpy(*buffer, PyString_AS_STRING(s), size + 1); } Py_DECREF(s); break; } #ifdef Py_USING_UNICODE case 'u': {/* raw unicode buffer (Py_UNICODE *) */ if (*format == '#') { /* any buffer-like object */ void **p = (void **)va_arg(*p_va, char **); FETCH_SIZE; if (PyUnicode_Check(arg)) { *p = PyUnicode_AS_UNICODE(arg); STORE_SIZE(PyUnicode_GET_SIZE(arg)); } else { return converterr("cannot convert raw buffers", arg, msgbuf, bufsize); } format++; } else { Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); if (PyUnicode_Check(arg)) *p = PyUnicode_AS_UNICODE(arg); else return converterr("unicode", arg, msgbuf, bufsize); } break; }#endif case 'S': { /* string object */ PyObject **p = va_arg(*p_va, PyObject **); if (PyString_Check(arg)) *p = arg; else return converterr("string", arg, msgbuf, bufsize); break; } #ifdef Py_USING_UNICODE case 'U': { /* Unicode object */ PyObject **p = va_arg(*p_va, PyObject **); if (PyUnicode_Check(arg)) *p = arg; else return converterr("unicode", arg, msgbuf, bufsize); break; }#endif case 'O': { /* object */ PyTypeObject *type; PyObject **p; if (*format == '!') { type = va_arg(*p_va, PyTypeObject*); p = va_arg(*p_va, PyObject **); format++; if (PyType_IsSubtype(arg->ob_type, type)) *p = arg; else return converterr(type->tp_name, arg, msgbuf, bufsize); } else if (*format == '?') { inquiry pred = va_arg(*p_va, inquiry); p = va_arg(*p_va, PyObject **); format++; if ((*pred)(arg)) *p = arg; else return converterr("(unspecified)", arg, msgbuf, bufsize); } else if (*format == '&') { typedef int (*converter)(PyObject *, void *); converter convert = va_arg(*p_va, converter); void *addr = va_arg(*p_va, void *); format++; if (! (*convert)(arg, addr)) return converterr("(unspecified)", arg, msgbuf, bufsize); } else { p = va_arg(*p_va, PyObject **); *p = arg; } break; } case 'w': { /* memory buffer, read-write access */ void **p = va_arg(*p_va, void **); PyBufferProcs *pb = arg->ob_type->tp_as_buffer; int count; if (pb == NULL || pb->bf_getwritebuffer == NULL || pb->bf_getsegcount == NULL) return converterr("read-write buffer", arg, msgbuf, bufsize); if ((*pb->bf_getsegcount)(arg, NULL) != 1) return converterr("single-segment read-write buffer", arg, msgbuf, bufsize); if ((count = pb->bf_getwritebuffer(arg, 0, p)) < 0) return converterr("(unspecified)", arg, msgbuf, bufsize); if (*format == '#') { FETCH_SIZE; STORE_SIZE(count); format++; } break; } case 't': { /* 8-bit character buffer, read-only access */ char **p = va_arg(*p_va, char **); PyBufferProcs *pb = arg->ob_type->tp_as_buffer; int count; if (*format++ != '#') return converterr( "invalid use of 't' format character", arg, msgbuf, bufsize); if (!PyType_HasFeature(arg->ob_type, Py_TPFLAGS_HAVE_GETCHARBUFFER) || pb == NULL || pb->bf_getcharbuffer == NULL || pb->bf_getsegcount == NULL) return converterr( "string or read-only character buffer", arg, msgbuf, bufsize); if (pb->bf_getsegcount(arg, NULL) != 1) return converterr( "string or single-segment read-only buffer", arg, msgbuf, bufsize); count = pb->bf_getcharbuffer(arg, 0, p); if (count < 0) return converterr("(unspecified)", arg, msgbuf, bufsize); { FETCH_SIZE; STORE_SIZE(count); } break; } default: return converterr("impossible<bad format char>", arg, msgbuf, bufsize); } *p_format = format; return NULL;} static Py_ssize_tconvertbuffer(PyObject *arg, void **p, char **errmsg){ PyBufferProcs *pb = arg->ob_type->tp_as_buffer; Py_ssize_t count; if (pb == NULL || pb->bf_getreadbuffer == NULL || pb->bf_getsegcount == NULL) { *errmsg = "string or read-only buffer"; return -1; } if ((*pb->bf_getsegcount)(arg, NULL) != 1) { *errmsg = "string or single-segment read-only buffer"; return -1; } if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) { *errmsg = "(unspecified)"; } return count;} /* Support for keyword arguments donated by Geoff Philbrick <philbric@delphi.hks.com> */ /* Return false (0) for error, else true. */intPyArg_ParseTupleAndKeywords(PyObject *args, PyObject *keywords, const char *format, char **kwlist, ...){ int retval; va_list va; if ((args == NULL || !PyTuple_Check(args)) || (keywords != NULL && !PyDict_Check(keywords)) || format == NULL || kwlist == NULL) { PyErr_BadInternalCall(); return 0; } va_start(va, kwlist); retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0); va_end(va); return retval;} int_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, PyObject *keywords, const char *format, char **kwlist, ...){ int retval; va_list va; if ((args == NULL || !PyTuple_Check(args)) || (keywords != NULL && !PyDict_Check(keywords)) || format == NULL || kwlist == NULL) { PyErr_BadInternalCall(); return 0; } va_start(va, kwlist); retval = vgetargskeywords(args, keywords, format, kwlist, &va, FLAG_SIZE_T); va_end(va); return retval;} intPyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *keywords, const char *format, char **kwlist, va_list va){ int retval; va_list lva; if ((args == NULL || !PyTuple_Check(args)) || (keywords != NULL && !PyDict_Check(keywords)) || format == NULL || kwlist == NULL) { PyErr_BadInternalCall(); return 0; } #ifdef VA_LIST_IS_ARRAY memcpy(lva, va, sizeof(va_list));#else#ifdef __va_copy __va_copy(lva, va);#else lva = va;#endif#endif retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0); return retval;} int_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, PyObject *keywords, const char *format, char **kwlist, va_list va){ int retval; va_list lva; if ((args == NULL || !PyTuple_Check(args)) || (keywords != NULL && !PyDict_Check(keywords)) || format == NULL || kwlist == NULL) { PyErr_BadInternalCall(); return 0; } #ifdef VA_LIST_IS_ARRAY memcpy(lva, va, sizeof(va_list));#else#ifdef __va_copy __va_copy(lva, va);#else lva = va;#endif#endif retval = vgetargskeywords(args, keywords, format, kwlist, &lva, FLAG_SIZE_T); return retval;} static intvgetargskeywords(PyObject *args, PyObject *keywords, const char *format, char **kwlist, va_list *p_va, int flags){ char msgbuf[512]; int levels[32]; const char *fname, *message; int min, max; const char *formatsave; int i, len, nargs, nkeywords; const char *msg; char **p; PyObject *freelist = NULL; assert(args != NULL && PyTuple_Check(args)); assert(keywords == NULL || PyDict_Check(keywords)); assert(format != NULL); assert(kwlist != NULL); assert(p_va != NULL); /* Search the format: message <- error msg, if any (else NULL). fname <- routine name, if any (else NULL). min <- # of required arguments, or -1 if all are required. max <- most arguments (required + optional). Check that kwlist has a non-NULL entry for each arg. Raise error if a tuple arg spec is found. */ fname = message = NULL; formatsave = format; p = kwlist; min = -1; max = 0; while ((i = *format++) != '\0') { if (isalpha(Py_CHARMASK(i)) && i != 'e') { max++; if (*p == NULL) { PyErr_SetString(PyExc_RuntimeError, "more argument specifiers than " "keyword list entries"); return 0; } p++; } else if (i == '|') min = max; else if (i == ':') { fname = format; break; } else if (i == ';') { message = format; break; } else if (i == '(') { PyErr_SetString(PyExc_RuntimeError, "tuple found in format when using keyword " "arguments"); return 0; } } format = formatsave; if (*p != NULL) { PyErr_SetString(PyExc_RuntimeError, "more keyword list entries than " "argument specifiers"); return 0; } if (min < 0) { /* All arguments are required. */ min = max; } nargs = PyTuple_GET_SIZE(args); nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords); /* make sure there are no duplicate values for an argument; its not clear when to use the term "keyword argument vs. keyword parameter in messages */ if (nkeywords > 0) { for (i = 0; i < nargs; i++) { const char *thiskw = kwlist[i]; if (thiskw == NULL) break; if (PyDict_GetItemString(keywords, thiskw)) { PyErr_Format(PyExc_TypeError, "keyword parameter '%s' was given " "by position and by name", thiskw); return 0; } else if (PyErr_Occurred()) return 0; } } /* required arguments missing from args can be supplied by keyword arguments; set len to the number of positional arguments, and, if that's less than the minimum required, add in the number of required arguments that are supplied by keywords */ len = nargs; if (nkeywords > 0 && nargs < min) { for (i = nargs; i < min; i++) { if (PyDict_GetItemString(keywords, kwlist[i])) len++; else if (PyErr_Occurred()) return 0; } } /* make sure we got an acceptable number of arguments; the message is a little confusing with keywords since keyword arguments which are supplied, but don't match the required arguments are not included in the "%d given" part of the message XXX and this isn't a bug!? */ if (len < min || max < len) { if (message == NULL) { PyOS_snprintf(msgbuf, sizeof(msgbuf), "%.200s%s takes %s %d argument%s " "(%d given)", fname==NULL ? "function" : fname, fname==NULL ? "" : "()", min==max ? "exactly" : len < min ? "at least" : "at most", len < min ? min : max, (len < min ? min : max) == 1 ? "" : "s", len); message = msgbuf; } PyErr_SetString(PyExc_TypeError, message); return 0; } /* convert the positional arguments */ for (i = 0; i < nargs; i++) { if (*format == '|') format++; msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); if (msg) { seterror(i+1, msg, levels, fname, message); return cleanreturn(0, freelist); } } /* handle no keyword parameters in call */ if (nkeywords == 0) return cleanreturn(1, freelist); /* convert the keyword arguments; this uses the format string where it was left after processing args */ for (i = nargs; i < max; i++) {Lines 1001–1500 of 1771. Previous lines Load more
Py_DECREF(s); return converterr( "(cleanup problem)", arg, msgbuf, bufsize); } } else { if (size + 1 > BUFFER_LEN) { Py_DECREF(s); return converterr( "(buffer overflow)", arg, msgbuf, bufsize); } } memcpy(*buffer, PyString_AS_STRING(s), size + 1); STORE_SIZE(size); } else { /* Using a 0-terminated buffer: - the encoded string has to be 0-terminated for this variant to work; if it is not, an error raised - a new buffer of the needed size is allocated and the data copied into it; *buffer is updated to point to the new buffer; the caller is responsible for PyMem_Free()ing it after usage */ if ((Py_ssize_t)strlen(PyString_AS_STRING(s)) != size) { Py_DECREF(s); return converterr( "(encoded string without NULL bytes)", arg, msgbuf, bufsize); } *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); return converterr("(memory error)", arg, msgbuf, bufsize); } if(addcleanup(*buffer, freelist)) { Py_DECREF(s); return converterr("(cleanup problem)", arg, msgbuf, bufsize); } memcpy(*buffer, PyString_AS_STRING(s), size + 1); } Py_DECREF(s); break; } #ifdef Py_USING_UNICODE case 'u': {/* raw unicode buffer (Py_UNICODE *) */ if (*format == '#') { /* any buffer-like object */ void **p = (void **)va_arg(*p_va, char **); FETCH_SIZE; if (PyUnicode_Check(arg)) { *p = PyUnicode_AS_UNICODE(arg); STORE_SIZE(PyUnicode_GET_SIZE(arg)); } else { return converterr("cannot convert raw buffers", arg, msgbuf, bufsize); } format++; } else { Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); if (PyUnicode_Check(arg)) *p = PyUnicode_AS_UNICODE(arg); else return converterr("unicode", arg, msgbuf, bufsize); } break; } #endif case 'S': { /* string object */ PyObject **p = va_arg(*p_va, PyObject **); if (PyString_Check(arg)) *p = arg; else return converterr("string", arg, msgbuf, bufsize); break; } #ifdef Py_USING_UNICODE case 'U': { /* Unicode object */ PyObject **p = va_arg(*p_va, PyObject **); if (PyUnicode_Check(arg)) *p = arg; else return converterr("unicode", arg, msgbuf, bufsize); break; } #endif case 'O': { /* object */ PyTypeObject *type; PyObject **p; if (*format == '!') { type = va_arg(*p_va, PyTypeObject*); p = va_arg(*p_va, PyObject **); format++; if (PyType_IsSubtype(arg->ob_type, type)) *p = arg; else return converterr(type->tp_name, arg, msgbuf, bufsize); } else if (*format == '?') { inquiry pred = va_arg(*p_va, inquiry); p = va_arg(*p_va, PyObject **); format++; if ((*pred)(arg)) *p = arg; else return converterr("(unspecified)", arg, msgbuf, bufsize); } else if (*format == '&') { typedef int (*converter)(PyObject *, void *); converter convert = va_arg(*p_va, converter); void *addr = va_arg(*p_va, void *); format++; if (! (*convert)(arg, addr)) return converterr("(unspecified)", arg, msgbuf, bufsize); } else { p = va_arg(*p_va, PyObject **); *p = arg; } break; } case 'w': { /* memory buffer, read-write access */ void **p = va_arg(*p_va, void **); PyBufferProcs *pb = arg->ob_type->tp_as_buffer; int count; if (pb == NULL || pb->bf_getwritebuffer == NULL || pb->bf_getsegcount == NULL) return converterr("read-write buffer", arg, msgbuf, bufsize); if ((*pb->bf_getsegcount)(arg, NULL) != 1) return converterr("single-segment read-write buffer", arg, msgbuf, bufsize); if ((count = pb->bf_getwritebuffer(arg, 0, p)) < 0) return converterr("(unspecified)", arg, msgbuf, bufsize); if (*format == '#') { FETCH_SIZE; STORE_SIZE(count); format++; } break; } case 't': { /* 8-bit character buffer, read-only access */ char **p = va_arg(*p_va, char **); PyBufferProcs *pb = arg->ob_type->tp_as_buffer; int count; if (*format++ != '#') return converterr( "invalid use of 't' format character", arg, msgbuf, bufsize); if (!PyType_HasFeature(arg->ob_type, Py_TPFLAGS_HAVE_GETCHARBUFFER) || pb == NULL || pb->bf_getcharbuffer == NULL || pb->bf_getsegcount == NULL) return converterr( "string or read-only character buffer", arg, msgbuf, bufsize); if (pb->bf_getsegcount(arg, NULL) != 1) return converterr( "string or single-segment read-only buffer", arg, msgbuf, bufsize); count = pb->bf_getcharbuffer(arg, 0, p); if (count < 0) return converterr("(unspecified)", arg, msgbuf, bufsize); { FETCH_SIZE; STORE_SIZE(count); } break; } default: return converterr("impossible<bad format char>", arg, msgbuf, bufsize); } *p_format = format; return NULL; } static Py_ssize_t convertbuffer(PyObject *arg, void **p, char **errmsg) { PyBufferProcs *pb = arg->ob_type->tp_as_buffer; Py_ssize_t count; if (pb == NULL || pb->bf_getreadbuffer == NULL || pb->bf_getsegcount == NULL) { *errmsg = "string or read-only buffer"; return -1; } if ((*pb->bf_getsegcount)(arg, NULL) != 1) { *errmsg = "string or single-segment read-only buffer"; return -1; } if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) { *errmsg = "(unspecified)"; } return count; } /* Support for keyword arguments donated by Geoff Philbrick <philbric@delphi.hks.com> */ /* Return false (0) for error, else true. */ int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *keywords, const char *format, char **kwlist, ...) { int retval; va_list va; if ((args == NULL || !PyTuple_Check(args)) || (keywords != NULL && !PyDict_Check(keywords)) || format == NULL || kwlist == NULL) { PyErr_BadInternalCall(); return 0; } va_start(va, kwlist); retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0); va_end(va); return retval; } int _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args, PyObject *keywords, const char *format, char **kwlist, ...) { int retval; va_list va; if ((args == NULL || !PyTuple_Check(args)) || (keywords != NULL && !PyDict_Check(keywords)) || format == NULL || kwlist == NULL) { PyErr_BadInternalCall(); return 0; } va_start(va, kwlist); retval = vgetargskeywords(args, keywords, format, kwlist, &va, FLAG_SIZE_T); va_end(va); return retval; } int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *keywords, const char *format, char **kwlist, va_list va) { int retval; va_list lva; if ((args == NULL || !PyTuple_Check(args)) || (keywords != NULL && !PyDict_Check(keywords)) || format == NULL || kwlist == NULL) { PyErr_BadInternalCall(); return 0; } #ifdef VA_LIST_IS_ARRAY memcpy(lva, va, sizeof(va_list)); #else #ifdef __va_copy __va_copy(lva, va); #else lva = va; #endif #endif retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0); return retval; } int _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args, PyObject *keywords, const char *format, char **kwlist, va_list va) { int retval; va_list lva; if ((args == NULL || !PyTuple_Check(args)) || (keywords != NULL && !PyDict_Check(keywords)) || format == NULL || kwlist == NULL) { PyErr_BadInternalCall(); return 0; } #ifdef VA_LIST_IS_ARRAY memcpy(lva, va, sizeof(va_list)); #else #ifdef __va_copy __va_copy(lva, va); #else lva = va; #endif #endif retval = vgetargskeywords(args, keywords, format, kwlist, &lva, FLAG_SIZE_T); return retval; } static int vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, char **kwlist, va_list *p_va, int flags) { char msgbuf[512]; int levels[32]; const char *fname, *message; int min, max; const char *formatsave; int i, len, nargs, nkeywords; const char *msg; char **p; PyObject *freelist = NULL; assert(args != NULL && PyTuple_Check(args)); assert(keywords == NULL || PyDict_Check(keywords)); assert(format != NULL); assert(kwlist != NULL); assert(p_va != NULL); /* Search the format: message <- error msg, if any (else NULL). fname <- routine name, if any (else NULL). min <- # of required arguments, or -1 if all are required. max <- most arguments (required + optional). Check that kwlist has a non-NULL entry for each arg. Raise error if a tuple arg spec is found. */ fname = message = NULL; formatsave = format; p = kwlist; min = -1; max = 0; while ((i = *format++) != '\0') { if (isalpha(Py_CHARMASK(i)) && i != 'e') { max++; if (*p == NULL) { PyErr_SetString(PyExc_RuntimeError, "more argument specifiers than " "keyword list entries"); return 0; } p++; } else if (i == '|') min = max; else if (i == ':') { fname = format; break; } else if (i == ';') { message = format; break; } else if (i == '(') { PyErr_SetString(PyExc_RuntimeError, "tuple found in format when using keyword " "arguments"); return 0; } } format = formatsave; if (*p != NULL) { PyErr_SetString(PyExc_RuntimeError, "more keyword list entries than " "argument specifiers"); return 0; } if (min < 0) { /* All arguments are required. */ min = max; } nargs = PyTuple_GET_SIZE(args); nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords); /* make sure there are no duplicate values for an argument; its not clear when to use the term "keyword argument vs. keyword parameter in messages */ if (nkeywords > 0) { for (i = 0; i < nargs; i++) { const char *thiskw = kwlist[i]; if (thiskw == NULL) break; if (PyDict_GetItemString(keywords, thiskw)) { PyErr_Format(PyExc_TypeError, "keyword parameter '%s' was given " "by position and by name", thiskw); return 0; } else if (PyErr_Occurred()) return 0; } } /* required arguments missing from args can be supplied by keyword arguments; set len to the number of positional arguments, and, if that's less than the minimum required, add in the number of required arguments that are supplied by keywords */ len = nargs; if (nkeywords > 0 && nargs < min) { for (i = nargs; i < min; i++) { if (PyDict_GetItemString(keywords, kwlist[i])) len++; else if (PyErr_Occurred()) return 0; } } /* make sure we got an acceptable number of arguments; the message is a little confusing with keywords since keyword arguments which are supplied, but don't match the required arguments are not included in the "%d given" part of the message XXX and this isn't a bug!? */ if (len < min || max < len) { if (message == NULL) { PyOS_snprintf(msgbuf, sizeof(msgbuf), "%.200s%s takes %s %d argument%s " "(%d given)", fname==NULL ? "function" : fname, fname==NULL ? "" : "()", min==max ? "exactly" : len < min ? "at least" : "at most", len < min ? min : max, (len < min ? min : max) == 1 ? "" : "s", len); message = msgbuf; } PyErr_SetString(PyExc_TypeError, message); return 0; } /* convert the positional arguments */ for (i = 0; i < nargs; i++) { if (*format == '|') format++; msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, flags, levels, msgbuf, sizeof(msgbuf), &freelist); if (msg) { seterror(i+1, msg, levels, fname, message); return cleanreturn(0, freelist); } } /* handle no keyword parameters in call */ if (nkeywords == 0) return cleanreturn(1, freelist); /* convert the keyword arguments; this uses the format string where it was left after processing args */ for (i = nargs; i < max; i++) {