Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

handle the case of a unicode argument to loads() differently

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...
commit e150d09b8ff6b3628a573c3b67b31b40677a94be 1 parent 5405ff8
@teepark teepark authored
Showing with 53 additions and 32 deletions.
  1. +27 −1 decoder.c
  2. +0 −2  py_yajl.h
  3. +26 −29 yajl.c
View
28 decoder.c
@@ -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"));
View
2  py_yajl.h
@@ -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
View
55 yajl.c
@@ -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) {
@@ -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;
}
Please sign in to comment.
Something went wrong with that request. Please try again.