diff options
Diffstat (limited to 'Python/getargs.c')
-rw-r--r-- | Python/getargs.c | 122 |
1 files changed, 64 insertions, 58 deletions
diff --git a/Python/getargs.c b/Python/getargs.c index 9858bd560c..8aab067865 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -20,12 +20,12 @@ int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, #ifdef HAVE_DECLSPEC_DLL /* Export functions */ -PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); -PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...); +PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...); +PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...); PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *, const char *, char **, ...); PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); -PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list); +PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list); PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *, const char *, char **, va_list); #endif @@ -56,18 +56,18 @@ typedef struct { /* Forward */ static int vgetargs1(PyObject *, const char *, va_list *, int); static void seterror(Py_ssize_t, const char *, int *, const char *, const char *); -static const char *convertitem(PyObject *, const char **, va_list *, int, int *, - char *, size_t, freelist_t *); -static const char *converttuple(PyObject *, const char **, va_list *, int, - int *, char *, size_t, int, freelist_t *); -static const char *convertsimple(PyObject *, const char **, va_list *, int, - char *, size_t, freelist_t *); -static Py_ssize_t convertbuffer(PyObject *, void **p, const char **); -static int getbuffer(PyObject *, Py_buffer *, const char**); +static char *convertitem(PyObject *, const char **, va_list *, int, int *, + char *, size_t, freelist_t *); +static char *converttuple(PyObject *, const char **, va_list *, int, + int *, char *, size_t, int, freelist_t *); +static char *convertsimple(PyObject *, const char **, va_list *, int, char *, + size_t, freelist_t *); +static Py_ssize_t convertbuffer(PyObject *, void **p, char **); +static int getbuffer(PyObject *, Py_buffer *, char**); static int vgetargskeywords(PyObject *, PyObject *, const char *, char **, va_list *, int); -static const char *skipitem(const char **, va_list *, int); +static char *skipitem(const char **, va_list *, int); int PyArg_Parse(PyObject *args, const char *format, ...) @@ -82,7 +82,7 @@ PyArg_Parse(PyObject *args, const char *format, ...) } int -_PyArg_Parse_SizeT(PyObject *args, const char *format, ...) +_PyArg_Parse_SizeT(PyObject *args, char *format, ...) { int retval; va_list va; @@ -107,7 +107,7 @@ PyArg_ParseTuple(PyObject *args, const char *format, ...) } int -_PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...) +_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...) { int retval; va_list va; @@ -130,7 +130,7 @@ PyArg_VaParse(PyObject *args, const char *format, va_list va) } int -_PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) +_PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va) { va_list lva; @@ -208,7 +208,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) int endfmt = 0; const char *formatsave = format; Py_ssize_t i, len; - const char *msg; + char *msg; int compat = flags & FLAG_COMPAT; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; freelist_t freelist; @@ -394,12 +394,7 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg); message = buf; } - if (msg[0] == '(') { - PyErr_SetString(PyExc_SystemError, message); - } - else { - PyErr_SetString(PyExc_TypeError, message); - } + PyErr_SetString(PyExc_TypeError, message); } @@ -421,7 +416,7 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, and msgbuf is returned. */ -static const char * +static char * converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, int *levels, char *msgbuf, size_t bufsize, int toplevel, freelist_t *freelist) @@ -479,7 +474,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, format = *p_format; for (i = 0; i < n; i++) { - const char *msg; + char *msg; PyObject *item; item = PySequence_GetItem(arg, i); if (item == NULL) { @@ -506,11 +501,11 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, /* Convert a single item. */ -static const char * +static char * convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist) { - const char *msg; + char *msg; const char *format = *p_format; if (*format == '(' /* ')' */) { @@ -535,7 +530,7 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, /* Format an error message generated by convertsimple(). */ -static const char * +static char * converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize) { assert(expected != NULL); @@ -577,7 +572,7 @@ float_argument_error(PyObject *arg) When you add new format codes, please don't forget poor skipitem() below. */ -static const char * +static char * convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, char *msgbuf, size_t bufsize, freelist_t *freelist) { @@ -862,7 +857,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, case 'y': {/* any bytes-like object */ void **p = (void **)va_arg(*p_va, char **); - const char *buf; + char *buf; Py_ssize_t count; if (*format == '*') { if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) @@ -909,7 +904,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, PyBuffer_FillInfo(p, arg, sarg, len, 1, 0); } else { /* any bytes-like object */ - const char *buf; + char *buf; if (getbuffer(arg, p, &buf) < 0) return converterr(buf, arg, msgbuf, bufsize); } @@ -939,7 +934,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } else { /* read-only bytes-like object */ /* XXX Really? */ - const char *buf; + char *buf; Py_ssize_t count = convertbuffer(arg, p, &buf); if (count < 0) return converterr(buf, arg, msgbuf, bufsize); @@ -1056,25 +1051,35 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, return converterr("(AsCharBuffer failed)", arg, msgbuf, bufsize); } - else if (PyUnicode_Check(arg)) { + else { + PyObject *u; + + /* Convert object to Unicode */ + u = PyUnicode_FromObject(arg); + if (u == NULL) + return converterr( + "string or unicode or text buffer", + arg, msgbuf, bufsize); + /* Encode object; use default error handling */ - s = PyUnicode_AsEncodedString(arg, + s = PyUnicode_AsEncodedString(u, encoding, NULL); + Py_DECREF(u); if (s == NULL) return converterr("(encoding failed)", arg, msgbuf, bufsize); - assert(PyBytes_Check(s)); + if (!PyBytes_Check(s)) { + Py_DECREF(s); + return converterr( + "(encoder failed to return bytes)", + arg, msgbuf, bufsize); + } size = PyBytes_GET_SIZE(s); ptr = PyBytes_AS_STRING(s); if (ptr == NULL) ptr = ""; } - else { - return converterr( - recode_strings ? "str" : "str, bytes or bytearray", - arg, msgbuf, bufsize); - } /* Write output; output is guaranteed to be 0-terminated */ if (*format == '#') { @@ -1124,7 +1129,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } else { if (size + 1 > BUFFER_LEN) { Py_DECREF(s); - PyErr_Format(PyExc_ValueError, + PyErr_Format(PyExc_TypeError, "encoded string too long " "(%zd, maximum length %zd)", (Py_ssize_t)size, (Py_ssize_t)(BUFFER_LEN-1)); @@ -1278,7 +1283,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } static Py_ssize_t -convertbuffer(PyObject *arg, void **p, const char **errmsg) +convertbuffer(PyObject *arg, void **p, char **errmsg) { PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; Py_ssize_t count; @@ -1300,7 +1305,7 @@ convertbuffer(PyObject *arg, void **p, const char **errmsg) } static int -getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg) +getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) { if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { *errmsg = "bytes-like object"; @@ -1502,7 +1507,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, keyword = kwlist[i]; if (*format == '|') { if (min != INT_MAX) { - PyErr_SetString(PyExc_SystemError, + PyErr_SetString(PyExc_RuntimeError, "Invalid format string (| specified twice)"); return cleanreturn(0, &freelist); } @@ -1511,14 +1516,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, format++; if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, + PyErr_SetString(PyExc_RuntimeError, "Invalid format string ($ before |)"); return cleanreturn(0, &freelist); } } if (*format == '$') { if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, + PyErr_SetString(PyExc_RuntimeError, "Invalid format string ($ specified twice)"); return cleanreturn(0, &freelist); } @@ -1536,7 +1541,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } } if (IS_END_OF_FORMAT(*format)) { - PyErr_Format(PyExc_SystemError, + PyErr_Format(PyExc_RuntimeError, "More keyword list entries (%d) than " "format specifiers (%d)", len, i); return cleanreturn(0, &freelist); @@ -1588,14 +1593,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, * keyword args */ msg = skipitem(&format, p_va, flags); if (msg) { - PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, + PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg, format); return cleanreturn(0, &freelist); } } if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { - PyErr_Format(PyExc_SystemError, + PyErr_Format(PyExc_RuntimeError, "more argument specifiers than keyword list entries " "(remaining format:'%s')", format); return cleanreturn(0, &freelist); @@ -1632,7 +1637,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } -static const char * +static char * skipitem(const char **p_format, va_list *p_va, int flags) { const char *format = *p_format; @@ -1725,7 +1730,7 @@ skipitem(const char **p_format, va_list *p_va, int flags) case '(': /* bypass tuple, not handled at all previously */ { - const char *msg; + char *msg; for (;;) { if (*format==')') break; @@ -1761,9 +1766,16 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m PyObject **o; va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, max); +#else + va_start(vargs); +#endif + assert(min >= 0); assert(min <= max); if (!PyTuple_Check(args)) { + va_end(vargs); PyErr_SetString(PyExc_SystemError, "PyArg_UnpackTuple() argument list is not a tuple"); return 0; @@ -1781,10 +1793,9 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m "unpacked tuple should have %s%zd elements," " but has %zd", (min == max ? "" : "at least "), min, l); + va_end(vargs); return 0; } - if (l == 0) - return 1; if (l > max) { if (name != NULL) PyErr_Format( @@ -1797,14 +1808,9 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m "unpacked tuple should have %s%zd elements," " but has %zd", (min == max ? "" : "at most "), max, l); + va_end(vargs); return 0; } - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, max); -#else - va_start(vargs); -#endif for (i = 0; i < l; i++) { o = va_arg(vargs, PyObject **); *o = PyTuple_GET_ITEM(args, i); |