Commit e2243331 authored by Marius Gedminas's avatar Marius Gedminas

Fix segfault in bucket_repr() on Python 3

Fixes #106.

The bug was in not checking the return value of
PyUnicode_AsLatin1String() and passing a NULL to PyOS_snprintf().

The fix is to use PyUnicode_FromFormat() and avoid all the hassle of
manual encoding/sprintf/decoding and even calling repr().
parent 189d7728
......@@ -1814,51 +1814,40 @@ static PyObject *
bucket_repr(Bucket *self)
{
PyObject *i, *r;
#ifdef PY3K
PyObject *rb;
#endif
#ifndef PY3K
char repr[10000];
int rv;
#endif
i = bucket_items(self, NULL, NULL);
if (!i)
{
return NULL;
}
#ifdef PY3K
r = PyUnicode_FromFormat("%s(%R)", Py_TYPE(self)->tp_name, i);
Py_DECREF(i);
return r;
#else
r = PyObject_Repr(i);
Py_DECREF(i);
if (!r)
{
return NULL;
}
#ifdef PY3K
rb = PyUnicode_AsLatin1String(r);
rv = PyOS_snprintf(repr, sizeof(repr),
"%s(%s)", Py_TYPE(self)->tp_name,
PyBytes_AsString(rb));
Py_DECREF(rb);
#else
rv = PyOS_snprintf(repr, sizeof(repr),
"%s(%s)", Py_TYPE(self)->tp_name,
PyBytes_AS_STRING(r));
#endif
if (rv > 0 && (size_t)rv < sizeof(repr))
{
Py_DECREF(r);
#ifdef PY3K
return PyUnicode_DecodeLatin1(repr, strlen(repr), "surrogateescape");
#else
return PyBytes_FromStringAndSize(repr, strlen(repr));
#endif
}
else
{
/* The static buffer wasn't big enough */
int size;
PyObject *s;
#ifdef PY3K
PyObject *result;
#endif
/* 3 for the parens and the null byte */
size = strlen(Py_TYPE(self)->tp_name) + PyBytes_GET_SIZE(r) + 3;
s = PyBytes_FromStringAndSize(NULL, size);
......@@ -1869,14 +1858,9 @@ bucket_repr(Bucket *self)
PyOS_snprintf(PyBytes_AS_STRING(s), size,
"%s(%s)", Py_TYPE(self)->tp_name, PyBytes_AS_STRING(r));
Py_DECREF(r);
#ifdef PY3K
result = PyUnicode_FromEncodedObject(s, "latin1", "surrogateescape");
Py_DECREF(s);
return result;
#else
return s;
#endif
}
#endif
}
static PyTypeObject BucketType = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment