From b048b26db00b57fe5f23b4b81eae90a06c98fb0b Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Wed, 28 Nov 2001 22:14:37 +0000 Subject: Two screwups fixed for sizeof(char *) instead of sizeof(char []). Also change all the helper functions to pass along the size of the msgbuf and use PyOS_snprintf() when writing into the buffer. --- Python/getargs.c | 159 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 77 deletions(-) diff --git a/Python/getargs.c b/Python/getargs.c index 8c4b039..3a31913 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -16,10 +16,11 @@ int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, /* Forward */ static int vgetargs1(PyObject *, char *, va_list *, int); static void seterror(int, char *, int *, char *, char *); -static char *convertitem(PyObject *, char **, va_list *, int *, char *); +static char *convertitem(PyObject *, char **, va_list *, int *, char *, + size_t); static char *converttuple(PyObject *, char **, va_list *, - int *, char *, int); -static char *convertsimple(PyObject *, char **, va_list *, char *); + int *, char *, size_t, int); +static char *convertsimple(PyObject *, char **, va_list *, char *, size_t); static int convertbuffer(PyObject *, void **p, char **); static int vgetargskeywords(PyObject *, PyObject *, @@ -151,7 +152,8 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat) PyErr_SetString(PyExc_TypeError, msgbuf); return 0; } - msg = convertitem(args, &format, p_va, levels, msgbuf); + msg = convertitem(args, &format, p_va, levels, msgbuf, + sizeof(msgbuf)); if (msg == NULL) return 1; seterror(levels[0], msg, levels+1, fname, message); @@ -194,7 +196,7 @@ vgetargs1(PyObject *args, char *format, va_list *p_va, int compat) if (*format == '|') format++; msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, - levels, msgbuf); + levels, msgbuf, sizeof(msgbuf)); if (msg) { seterror(i+1, msg, levels, fname, message); return 0; @@ -271,7 +273,7 @@ seterror(int iarg, char *msg, int *levels, char *fname, char *message) static char * converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels, - char *msgbuf, int toplevel) + char *msgbuf, size_t bufsize, int toplevel) { int level = 0; int n = 0; @@ -298,7 +300,7 @@ converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels, if (!PySequence_Check(arg) || PyString_Check(arg)) { levels[0] = 0; - PyOS_snprintf(msgbuf, sizeof(msgbuf), + PyOS_snprintf(msgbuf, bufsize, toplevel ? "expected %d arguments, not %.50s" : "must be %d-item sequence, not %.50s", n, @@ -308,7 +310,7 @@ converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels, if ((i = PySequence_Size(arg)) != n) { levels[0] = 0; - PyOS_snprintf(msgbuf, sizeof(msgbuf), + PyOS_snprintf(msgbuf, bufsize, toplevel ? "expected %d arguments, not %d" : "must be sequence of length %d, not %d", n, i); @@ -320,7 +322,8 @@ converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels, char *msg; PyObject *item; item = PySequence_GetItem(arg, i); - msg = convertitem(item, &format, p_va, levels+1, msgbuf); + msg = convertitem(item, &format, p_va, levels+1, msgbuf, + bufsize); /* PySequence_GetItem calls tp->sq_item, which INCREFs */ Py_XDECREF(item); if (msg != NULL) { @@ -338,19 +341,20 @@ converttuple(PyObject *arg, char **p_format, va_list *p_va, int *levels, static char * convertitem(PyObject *arg, char **p_format, va_list *p_va, int *levels, - char *msgbuf) + char *msgbuf, size_t bufsize) { char *msg; char *format = *p_format; if (*format == '(' /* ')' */) { format++; - msg = converttuple(arg, &format, p_va, levels, msgbuf, 0); + msg = converttuple(arg, &format, p_va, levels, msgbuf, + bufsize, 0); if (msg == NULL) format++; } else { - msg = convertsimple(arg, &format, p_va, msgbuf); + msg = convertsimple(arg, &format, p_va, msgbuf, bufsize); if (msg != NULL) levels[0] = 0; } @@ -367,14 +371,13 @@ convertitem(PyObject *arg, char **p_format, va_list *p_va, int *levels, /* Format an error message generated by convertsimple(). */ static char * -converterr(char *expected, PyObject *arg, char *msgbuf) +converterr(char *expected, PyObject *arg, char *msgbuf, size_t bufsize) { assert(expected != NULL); assert(arg != NULL); - /* XXX use snprintf? */ - sprintf(msgbuf, - "must be %.50s, not %.50s", expected, - arg == Py_None ? "None" : arg->ob_type->tp_name); + PyOS_snprintf(msgbuf, bufsize, + "must be %.50s, not %.50s", expected, + arg == Py_None ? "None" : arg->ob_type->tp_name); return msgbuf; } @@ -388,7 +391,8 @@ converterr(char *expected, PyObject *arg, char *msgbuf) */ static char * -convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) +convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf, + size_t bufsize) { char *format = *p_format; char c = *format++; @@ -400,16 +404,16 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) char *p = va_arg(*p_va, char *); long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); else if (ival < 0) { PyErr_SetString(PyExc_OverflowError, "unsigned byte integer is less than minimum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else if (ival > UCHAR_MAX) { PyErr_SetString(PyExc_OverflowError, "unsigned byte integer is greater than maximum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else *p = (unsigned char) ival; @@ -421,16 +425,16 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) char *p = va_arg(*p_va, char *); long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); else if (ival < SCHAR_MIN) { PyErr_SetString(PyExc_OverflowError, "byte-sized integer bitfield is less than minimum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else if (ival > (int)UCHAR_MAX) { PyErr_SetString(PyExc_OverflowError, "byte-sized integer bitfield is greater than maximum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else *p = (unsigned char) ival; @@ -441,16 +445,16 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) short *p = va_arg(*p_va, short *); long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); else if (ival < SHRT_MIN) { PyErr_SetString(PyExc_OverflowError, "signed short integer is less than minimum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else if (ival > SHRT_MAX) { PyErr_SetString(PyExc_OverflowError, "signed short integer is greater than maximum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else *p = (short) ival; @@ -462,16 +466,16 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) unsigned short *p = va_arg(*p_va, unsigned short *); long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); else if (ival < SHRT_MIN) { PyErr_SetString(PyExc_OverflowError, "short integer bitfield is less than minimum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else if (ival > USHRT_MAX) { PyErr_SetString(PyExc_OverflowError, "short integer bitfield is greater than maximum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else *p = (unsigned short) ival; @@ -482,16 +486,16 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) int *p = va_arg(*p_va, int *); long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); else if (ival > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "signed integer is greater than maximum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else if (ival < INT_MIN) { PyErr_SetString(PyExc_OverflowError, "signed integer is less than minimum"); - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); } else *p = ival; @@ -502,7 +506,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) long *p = va_arg(*p_va, long *); long ival = PyInt_AsLong(arg); if (ival == -1 && PyErr_Occurred()) - return converterr("integer", arg, msgbuf); + return converterr("integer", arg, msgbuf, bufsize); else *p = ival; break; @@ -513,7 +517,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) LONG_LONG *p = va_arg( *p_va, LONG_LONG * ); LONG_LONG ival = PyLong_AsLongLong( arg ); if( ival == (LONG_LONG)-1 && PyErr_Occurred() ) { - return converterr("long", arg, msgbuf); + return converterr("long", arg, msgbuf, bufsize); } else { *p = ival; } @@ -525,7 +529,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) float *p = va_arg(*p_va, float *); double dval = PyFloat_AsDouble(arg); if (PyErr_Occurred()) - return converterr("float", arg, msgbuf); + return converterr("float", arg, msgbuf, bufsize); else *p = (float) dval; break; @@ -535,7 +539,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) double *p = va_arg(*p_va, double *); double dval = PyFloat_AsDouble(arg); if (PyErr_Occurred()) - return converterr("float", arg, msgbuf); + return converterr("float", arg, msgbuf, bufsize); else *p = dval; break; @@ -547,7 +551,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) Py_complex cval; cval = PyComplex_AsCComplex(arg); if (PyErr_Occurred()) - return converterr("complex", arg, msgbuf); + return converterr("complex", arg, msgbuf, bufsize); else *p = cval; break; @@ -559,7 +563,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (PyString_Check(arg) && PyString_Size(arg) == 1) *p = PyString_AS_STRING(arg)[0]; else - return converterr("char", arg, msgbuf); + return converterr("char", arg, msgbuf, bufsize); break; } @@ -577,7 +581,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) return converterr(CONV_UNICODE, - arg, msgbuf); + arg, msgbuf, bufsize); *p = PyString_AS_STRING(uarg); *q = PyString_GET_SIZE(uarg); } @@ -586,7 +590,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) char *buf; int count = convertbuffer(arg, p, &buf); if (count < 0) - return converterr(buf, arg, msgbuf); + return converterr(buf, arg, msgbuf, bufsize); *q = count; } format++; @@ -600,15 +604,15 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) return converterr(CONV_UNICODE, - arg, msgbuf); + arg, msgbuf, bufsize); *p = PyString_AS_STRING(uarg); } #endif else - return converterr("string", arg, msgbuf); + return converterr("string", arg, msgbuf, bufsize); if ((int)strlen(*p) != PyString_Size(arg)) return converterr("string without null bytes", - arg, msgbuf); + arg, msgbuf, bufsize); } break; } @@ -631,7 +635,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) return converterr(CONV_UNICODE, - arg, msgbuf); + arg, msgbuf, bufsize); *p = PyString_AS_STRING(uarg); *q = PyString_GET_SIZE(uarg); } @@ -640,7 +644,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) char *buf; int count = convertbuffer(arg, p, &buf); if (count < 0) - return converterr(buf, arg, msgbuf); + return converterr(buf, arg, msgbuf, bufsize); *q = count; } format++; @@ -656,13 +660,13 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) uarg = UNICODE_DEFAULT_ENCODING(arg); if (uarg == NULL) return converterr(CONV_UNICODE, - arg, msgbuf); + arg, msgbuf, bufsize); *p = PyString_AS_STRING(uarg); } #endif else return converterr("string or None", - arg, msgbuf); + arg, msgbuf, bufsize); if (*format == '#') { int *q = va_arg(*p_va, int *); if (arg == Py_None) @@ -675,7 +679,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) (int)strlen(*p) != PyString_Size(arg)) return converterr( "string without null bytes or None", - arg, msgbuf); + arg, msgbuf, bufsize); } break; } @@ -704,12 +708,12 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) else return converterr( "(unknown parser marker combination)", - arg, msgbuf); + arg, msgbuf, bufsize); buffer = (char **)va_arg(*p_va, char **); format++; if (buffer == NULL) return converterr("(buffer is NULL)", - arg, msgbuf); + arg, msgbuf, bufsize); /* Encode object */ if (!recode_strings && PyString_Check(arg)) { @@ -725,7 +729,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (u == NULL) return converterr( "string or unicode or text buffer", - arg, msgbuf); + arg, msgbuf, bufsize); /* Encode object; use default error handling */ s = PyUnicode_AsEncodedString(u, @@ -734,15 +738,15 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) Py_DECREF(u); if (s == NULL) return converterr("(encoding failed)", - arg, msgbuf); + arg, msgbuf, bufsize); if (!PyString_Check(s)) { Py_DECREF(s); return converterr( "(encoder failed to return a string)", - arg, msgbuf); + arg, msgbuf, bufsize); } #else - return converterr("string", arg, msgbuf); + return converterr("string", arg, msgbuf, bufsize); #endif } size = PyString_GET_SIZE(s); @@ -776,21 +780,21 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (buffer_len == NULL) return converterr( "(buffer_len is NULL)", - arg, msgbuf); + arg, msgbuf, bufsize); if (*buffer == NULL) { *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); return converterr( "(memory error)", - arg, msgbuf); + arg, msgbuf, bufsize); } } else { if (size + 1 > *buffer_len) { Py_DECREF(s); return converterr( "(buffer overflow)", - arg, msgbuf); + arg, msgbuf, bufsize); } } memcpy(*buffer, @@ -814,12 +818,12 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if ((int)strlen(PyString_AS_STRING(s)) != size) return converterr( "(encoded string without NULL bytes)", - arg, msgbuf); + arg, msgbuf, bufsize); *buffer = PyMem_NEW(char, size + 1); if (*buffer == NULL) { Py_DECREF(s); return converterr("(memory error)", - arg, msgbuf); + arg, msgbuf, bufsize); } memcpy(*buffer, PyString_AS_STRING(s), @@ -838,7 +842,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) int count = convertbuffer(arg, p, &buf); if (count < 0) - return converterr(buf, arg, msgbuf); + return converterr(buf, arg, msgbuf, bufsize); *q = count/(sizeof(Py_UNICODE)); format++; } else { @@ -847,7 +851,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (PyUnicode_Check(arg)) *p = PyUnicode_AS_UNICODE(arg); else - return converterr("unicode", arg, msgbuf); + return converterr("unicode", arg, msgbuf, bufsize); } break; } @@ -858,7 +862,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (PyString_Check(arg)) *p = arg; else - return converterr("string", arg, msgbuf); + return converterr("string", arg, msgbuf, bufsize); break; } @@ -868,7 +872,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (PyUnicode_Check(arg)) *p = arg; else - return converterr("unicode", arg, msgbuf); + return converterr("unicode", arg, msgbuf, bufsize); break; } #endif @@ -883,7 +887,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (PyType_IsSubtype(arg->ob_type, type)) *p = arg; else - return converterr(type->tp_name, arg, msgbuf); + return converterr(type->tp_name, arg, msgbuf, bufsize); } else if (*format == '?') { @@ -894,7 +898,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) *p = arg; else return converterr("(unspecified)", - arg, msgbuf); + arg, msgbuf, bufsize); } else if (*format == '&') { @@ -904,7 +908,7 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) format++; if (! (*convert)(arg, addr)) return converterr("(unspecified)", - arg, msgbuf); + arg, msgbuf, bufsize); } else { p = va_arg(*p_va, PyObject **); @@ -922,12 +926,12 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (pb == NULL || pb->bf_getwritebuffer == NULL || pb->bf_getsegcount == NULL) - return converterr("read-write buffer", arg, msgbuf); + return converterr("read-write buffer", arg, msgbuf, bufsize); if ((*pb->bf_getsegcount)(arg, NULL) != 1) return converterr("single-segment read-write buffer", - arg, msgbuf); + arg, msgbuf, bufsize); if ((count = pb->bf_getwritebuffer(arg, 0, p)) < 0) - return converterr("(unspecified)", arg, msgbuf); + return converterr("(unspecified)", arg, msgbuf, bufsize); if (*format == '#') { int *q = va_arg(*p_va, int *); @@ -945,29 +949,29 @@ convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf) if (*format++ != '#') return converterr( "invalid use of 't' format character", - arg, msgbuf); + 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); + arg, msgbuf, bufsize); if (pb->bf_getsegcount(arg, NULL) != 1) return converterr( "string or single-segment read-only buffer", - arg, msgbuf); + arg, msgbuf, bufsize); count = pb->bf_getcharbuffer(arg, 0, p); if (count < 0) - return converterr("(unspecified)", arg, msgbuf); + return converterr("(unspecified)", arg, msgbuf, bufsize); *va_arg(*p_va, int *) = count; break; } default: - return converterr("impossible", arg, msgbuf); + return converterr("impossible", arg, msgbuf, bufsize); } @@ -1157,7 +1161,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, if (*format == '|') format++; msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va, - levels, msgbuf); + levels, msgbuf, sizeof(msgbuf)); if (msg) { seterror(i+1, msg, levels, fname, message); return 0; @@ -1177,7 +1181,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, item = PyDict_GetItemString(keywords, kwlist[i]); if (item != NULL) { Py_INCREF(item); - msg = convertitem(item, &format, p_va, levels, msgbuf); + msg = convertitem(item, &format, p_va, levels, msgbuf, + sizeof(msgbuf)); Py_DECREF(item); if (msg) { seterror(i+1, msg, levels, fname, message); -- cgit v0.12