Skip to content
This repository has been archived by the owner on Mar 8, 2018. It is now read-only.

Commit

Permalink
handle the case of a unicode argument to loads() differently
Browse files Browse the repository at this point in the history
unfortunately this just needs to be inlined, a separate utf8_z_hash
function won't work. the reason being that PyString_AsStringAndSize
gives access to the string object's internal buffer rather than copying,
and that string object was being decrefed away at the end of the
function, but the buffer we got out of it still needed to be usable.
  • Loading branch information
teepark committed Apr 27, 2011
1 parent 5405ff8 commit e150d09
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 32 deletions.
28 changes: 27 additions & 1 deletion decoder.c
Expand Up @@ -281,11 +281,37 @@ PyObject *py_yajldecoder_decode(PYARGS)
{
_YajlDecoder *decoder = (_YajlDecoder *)(self);
char *buffer = NULL;
PyObject *pybuffer = NULL;
PyObject *alternate = NULL;
Py_ssize_t buflen = 0;

if (utf8_z_hash_arg(self, args, kwargs, &buffer, &buflen))
if (!PyArg_ParseTuple(args, "O", &pybuffer))
return NULL;

Py_INCREF(pybuffer);

if (PyUnicode_Check(pybuffer)) {
if (!(alternate = PyUnicode_AsUTF8String(pybuffer))) {
Py_DECREF(pybuffer);
return NULL;
}
Py_DECREF(pybuffer);
pybuffer = alternate;
}

if (PyString_Check(pybuffer)) {
if (PyString_AsStringAndSize(pybuffer, &buffer, &buflen)) {
Py_DECREF(pybuffer);
return NULL;
}
} else {
/* really seems like this should be a TypeError, but
tests/unit.py:ErrorCasesTests.test_None disagrees */
Py_DECREF(pybuffer);
PyErr_SetString(PyExc_ValueError, "string or unicode expected");
return NULL;
}

if (!buflen) {
PyErr_SetObject(PyExc_ValueError,
PyUnicode_FromString("Cannot parse an empty buffer"));
Expand Down
2 changes: 0 additions & 2 deletions py_yajl.h
Expand Up @@ -101,7 +101,5 @@ extern int yajlencoder_init(PYARGS);
extern void yajlencoder_dealloc(_YajlEncoder *self);
extern PyObject *_internal_encode(_YajlEncoder *self, PyObject *obj, yajl_gen_config config);

extern int utf8_z_hash_arg(PYARGS, char **buffer, Py_ssize_t *buflen);

#endif

55 changes: 26 additions & 29 deletions yajl.c
Expand Up @@ -134,45 +134,41 @@ static PyTypeObject YajlEncoderType = {
0, /* tp_alloc */
};

int utf8_z_hash_arg(PYARGS, char **buffer, Py_ssize_t *buflen) {
PyObject *pybuffer;
PyObject *pystr;
int rc;
static PyObject *py_loads(PYARGS)
{
PyObject *decoder = NULL;
PyObject *result = NULL;
PyObject *pybuffer = NULL;
char *buffer = NULL;
Py_ssize_t buflen = 0;

if (!PyArg_ParseTuple(args, "O", &pybuffer))
return -1;
return NULL;

Py_INCREF(pybuffer);

if (PyUnicode_Check(pybuffer)) {
pystr = PyUnicode_AsUTF8String(pybuffer);
if (!pystr) return -1;

if (!(result = PyUnicode_AsUTF8String(pybuffer))) {
Py_DECREF(pybuffer);
return NULL;
}
Py_DECREF(pybuffer);
pybuffer = pystr;
pybuffer = result;
result = NULL;
}

if (!PyString_Check(pybuffer)) {
/* really seems like this should be a TypeError,
* but tests/unit.py:ErrorCasesTests.test_None disagrees
*/
if (PyString_Check(pybuffer)) {
if (PyString_AsStringAndSize(pybuffer, &buffer, &buflen)) {
Py_DECREF(pybuffer);
return NULL;
}
} else {
/* really seems like this should be a TypeError, but
tests/unit.py:ErrorCasesTests.test_None disagrees */
Py_DECREF(pybuffer);
PyErr_SetString(PyExc_ValueError, "string or unicode expected");
return -1;
}

rc = PyString_AsStringAndSize(pybuffer, buffer, buflen);
Py_DECREF(pybuffer);
return rc;
}

static PyObject *py_loads(PYARGS)
{
PyObject *decoder = NULL;
PyObject *result = NULL;
char *buffer = NULL;
Py_ssize_t buflen = 0;

if (utf8_z_hash_arg(self, args, kwargs, &buffer, &buflen))
return NULL;
}

decoder = PyObject_Call((PyObject *)(&YajlDecoderType), NULL, NULL);
if (decoder == NULL) {
Expand All @@ -181,6 +177,7 @@ static PyObject *py_loads(PYARGS)

result = _internal_decode(
(_YajlDecoder *)decoder, buffer, (unsigned int)buflen);
Py_DECREF(pybuffer);
Py_XDECREF(decoder);
return result;
}
Expand Down

0 comments on commit e150d09

Please sign in to comment.