diff options
Diffstat (limited to 'Python/getargs.c')
-rw-r--r-- | Python/getargs.c | 122 |
1 files changed, 58 insertions, 64 deletions
diff --git a/Python/getargs.c b/Python/getargs.c index 8aab067..9858bd5 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 *, char *, ...); -PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...); +PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...); +PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const 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 *, char *, va_list); +PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const 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 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 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 int vgetargskeywords(PyObject *, PyObject *, const char *, char **, va_list *, int); -static char *skipitem(const char **, va_list *, int); +static const 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, char *format, ...) +_PyArg_Parse_SizeT(PyObject *args, const char *format, ...) { int retval; va_list va; @@ -107,7 +107,7 @@ PyArg_ParseTuple(PyObject *args, const char *format, ...) } int -_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...) +_PyArg_ParseTuple_SizeT(PyObject *args, const 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, char *format, va_list va) +_PyArg_VaParse_SizeT(PyObject *args, const 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; - char *msg; + const char *msg; int compat = flags & FLAG_COMPAT; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; freelist_t freelist; @@ -394,7 +394,12 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg); message = buf; } - PyErr_SetString(PyExc_TypeError, message); + if (msg[0] == '(') { + PyErr_SetString(PyExc_SystemError, message); + } + else { + PyErr_SetString(PyExc_TypeError, message); + } } @@ -416,7 +421,7 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname, and msgbuf is returned. */ -static char * +static const 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) @@ -474,7 +479,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, format = *p_format; for (i = 0; i < n; i++) { - char *msg; + const char *msg; PyObject *item; item = PySequence_GetItem(arg, i); if (item == NULL) { @@ -501,11 +506,11 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, /* Convert a single item. */ -static char * +static const char * convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist) { - char *msg; + const char *msg; const char *format = *p_format; if (*format == '(' /* ')' */) { @@ -530,7 +535,7 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, /* Format an error message generated by convertsimple(). */ -static char * +static const char * converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize) { assert(expected != NULL); @@ -572,7 +577,7 @@ float_argument_error(PyObject *arg) When you add new format codes, please don't forget poor skipitem() below. */ -static char * +static const char * convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, char *msgbuf, size_t bufsize, freelist_t *freelist) { @@ -857,7 +862,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 **); - char *buf; + const char *buf; Py_ssize_t count; if (*format == '*') { if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) @@ -904,7 +909,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 */ - char *buf; + const char *buf; if (getbuffer(arg, p, &buf) < 0) return converterr(buf, arg, msgbuf, bufsize); } @@ -934,7 +939,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } else { /* read-only bytes-like object */ /* XXX Really? */ - char *buf; + const char *buf; Py_ssize_t count = convertbuffer(arg, p, &buf); if (count < 0) return converterr(buf, arg, msgbuf, bufsize); @@ -1051,35 +1056,25 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, return converterr("(AsCharBuffer failed)", arg, msgbuf, bufsize); } - 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); - + else if (PyUnicode_Check(arg)) { /* Encode object; use default error handling */ - s = PyUnicode_AsEncodedString(u, + s = PyUnicode_AsEncodedString(arg, encoding, NULL); - Py_DECREF(u); if (s == NULL) return converterr("(encoding failed)", arg, msgbuf, bufsize); - if (!PyBytes_Check(s)) { - Py_DECREF(s); - return converterr( - "(encoder failed to return bytes)", - arg, msgbuf, bufsize); - } + assert(PyBytes_Check(s)); 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 == '#') { @@ -1129,7 +1124,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_TypeError, + PyErr_Format(PyExc_ValueError, "encoded string too long " "(%zd, maximum length %zd)", (Py_ssize_t)size, (Py_ssize_t)(BUFFER_LEN-1)); @@ -1283,7 +1278,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, } static Py_ssize_t -convertbuffer(PyObject *arg, void **p, char **errmsg) +convertbuffer(PyObject *arg, void **p, const char **errmsg) { PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer; Py_ssize_t count; @@ -1305,7 +1300,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg) } static int -getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) +getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg) { if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { *errmsg = "bytes-like object"; @@ -1507,7 +1502,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, keyword = kwlist[i]; if (*format == '|') { if (min != INT_MAX) { - PyErr_SetString(PyExc_RuntimeError, + PyErr_SetString(PyExc_SystemError, "Invalid format string (| specified twice)"); return cleanreturn(0, &freelist); } @@ -1516,14 +1511,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, format++; if (max != INT_MAX) { - PyErr_SetString(PyExc_RuntimeError, + PyErr_SetString(PyExc_SystemError, "Invalid format string ($ before |)"); return cleanreturn(0, &freelist); } } if (*format == '$') { if (max != INT_MAX) { - PyErr_SetString(PyExc_RuntimeError, + PyErr_SetString(PyExc_SystemError, "Invalid format string ($ specified twice)"); return cleanreturn(0, &freelist); } @@ -1541,7 +1536,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } } if (IS_END_OF_FORMAT(*format)) { - PyErr_Format(PyExc_RuntimeError, + PyErr_Format(PyExc_SystemError, "More keyword list entries (%d) than " "format specifiers (%d)", len, i); return cleanreturn(0, &freelist); @@ -1593,14 +1588,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, * keyword args */ msg = skipitem(&format, p_va, flags); if (msg) { - PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg, + PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, format); return cleanreturn(0, &freelist); } } if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { - PyErr_Format(PyExc_RuntimeError, + PyErr_Format(PyExc_SystemError, "more argument specifiers than keyword list entries " "(remaining format:'%s')", format); return cleanreturn(0, &freelist); @@ -1637,7 +1632,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, } -static char * +static const char * skipitem(const char **p_format, va_list *p_va, int flags) { const char *format = *p_format; @@ -1730,7 +1725,7 @@ skipitem(const char **p_format, va_list *p_va, int flags) case '(': /* bypass tuple, not handled at all previously */ { - char *msg; + const char *msg; for (;;) { if (*format==')') break; @@ -1766,16 +1761,9 @@ 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; @@ -1793,9 +1781,10 @@ 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( @@ -1808,9 +1797,14 @@ 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); |