summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Python/getargs.c159
1 files 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<b>", arg, msgbuf);
+ return converterr("integer<b>", arg, msgbuf, bufsize);
else if (ival < 0) {
PyErr_SetString(PyExc_OverflowError,
"unsigned byte integer is less than minimum");
- return converterr("integer<b>", arg, msgbuf);
+ return converterr("integer<b>", arg, msgbuf, bufsize);
}
else if (ival > UCHAR_MAX) {
PyErr_SetString(PyExc_OverflowError,
"unsigned byte integer is greater than maximum");
- return converterr("integer<b>", arg, msgbuf);
+ return converterr("integer<b>", 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<b>", arg, msgbuf);
+ return converterr("integer<b>", arg, msgbuf, bufsize);
else if (ival < SCHAR_MIN) {
PyErr_SetString(PyExc_OverflowError,
"byte-sized integer bitfield is less than minimum");
- return converterr("integer<B>", arg, msgbuf);
+ return converterr("integer<B>", arg, msgbuf, bufsize);
}
else if (ival > (int)UCHAR_MAX) {
PyErr_SetString(PyExc_OverflowError,
"byte-sized integer bitfield is greater than maximum");
- return converterr("integer<B>", arg, msgbuf);
+ return converterr("integer<B>", 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<h>", arg, msgbuf);
+ return converterr("integer<h>", arg, msgbuf, bufsize);
else if (ival < SHRT_MIN) {
PyErr_SetString(PyExc_OverflowError,
"signed short integer is less than minimum");
- return converterr("integer<h>", arg, msgbuf);
+ return converterr("integer<h>", arg, msgbuf, bufsize);
}
else if (ival > SHRT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"signed short integer is greater than maximum");
- return converterr("integer<h>", arg, msgbuf);
+ return converterr("integer<h>", 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<H>", arg, msgbuf);
+ return converterr("integer<H>", arg, msgbuf, bufsize);
else if (ival < SHRT_MIN) {
PyErr_SetString(PyExc_OverflowError,
"short integer bitfield is less than minimum");
- return converterr("integer<H>", arg, msgbuf);
+ return converterr("integer<H>", arg, msgbuf, bufsize);
}
else if (ival > USHRT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"short integer bitfield is greater than maximum");
- return converterr("integer<H>", arg, msgbuf);
+ return converterr("integer<H>", 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<i>", arg, msgbuf);
+ return converterr("integer<i>", arg, msgbuf, bufsize);
else if (ival > INT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"signed integer is greater than maximum");
- return converterr("integer<i>", arg, msgbuf);
+ return converterr("integer<i>", arg, msgbuf, bufsize);
}
else if (ival < INT_MIN) {
PyErr_SetString(PyExc_OverflowError,
"signed integer is less than minimum");
- return converterr("integer<i>", arg, msgbuf);
+ return converterr("integer<i>", 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<l>", arg, msgbuf);
+ return converterr("integer<l>", 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<L>", arg, msgbuf);
+ return converterr("long<L>", 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<f>", arg, msgbuf);
+ return converterr("float<f>", 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<d>", arg, msgbuf);
+ return converterr("float<d>", 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<D>", arg, msgbuf);
+ return converterr("complex<D>", 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<e>", arg, msgbuf);
+ return converterr("string<e>", 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<bad format char>", arg, msgbuf);
+ return converterr("impossible<bad format char>", 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);