summaryrefslogtreecommitdiff
path: root/Modules/cjkcodecs/multibytecodec.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/cjkcodecs/multibytecodec.c')
-rw-r--r--Modules/cjkcodecs/multibytecodec.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index 7b04f020c9..c032cdb0ed 100644
--- a/Modules/cjkcodecs/multibytecodec.c
+++ b/Modules/cjkcodecs/multibytecodec.c
@@ -316,15 +316,15 @@ multibytecodec_encerror(MultibyteCodec *codec,
goto errorexit;
if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
- !PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) ||
+ (!PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) && !PyBytes_Check(tobj)) ||
!PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) {
PyErr_SetString(PyExc_TypeError,
"encoding error handler must return "
- "(unicode, int) tuple");
+ "(str, int) tuple");
goto errorexit;
}
- {
+ if (PyUnicode_Check(tobj)) {
const Py_UNICODE *uraw = PyUnicode_AS_UNICODE(tobj);
retstr = multibytecodec_encode(codec, state, &uraw,
@@ -333,6 +333,10 @@ multibytecodec_encerror(MultibyteCodec *codec,
if (retstr == NULL)
goto errorexit;
}
+ else {
+ Py_INCREF(tobj);
+ retstr = tobj;
+ }
assert(PyBytes_Check(retstr));
retstrsize = PyBytes_GET_SIZE(retstr);
@@ -439,14 +443,16 @@ multibytecodec_decerror(MultibyteCodec *codec,
!PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) {
PyErr_SetString(PyExc_TypeError,
"decoding error handler must return "
- "(unicode, int) tuple");
+ "(str, int) tuple");
goto errorexit;
}
+ if (PyUnicode_AsUnicode(retuni) == NULL)
+ goto errorexit;
retunisize = PyUnicode_GET_SIZE(retuni);
if (retunisize > 0) {
REQUIRE_DECODEBUFFER(buf, retunisize);
- memcpy((char *)buf->outbuf, PyUnicode_AS_DATA(retuni),
+ memcpy((char *)buf->outbuf, PyUnicode_AS_UNICODE(retuni),
retunisize * Py_UNICODE_SIZE);
buf->outbuf += retunisize;
}
@@ -483,6 +489,7 @@ multibytecodec_encode(MultibyteCodec *codec,
return PyBytes_FromStringAndSize(NULL, 0);
buf.excobj = NULL;
+ buf.outobj = NULL;
buf.inbuf = buf.inbuf_top = *data;
buf.inbuf_end = buf.inbuf_top + datalen;
@@ -573,8 +580,11 @@ MultibyteCodec_Encode(MultibyteCodecObject *self,
}
}
- data = PyUnicode_AS_UNICODE(arg);
- datalen = PyUnicode_GET_SIZE(arg);
+ data = PyUnicode_AsUnicodeAndSize(arg, &datalen);
+ if (data == NULL) {
+ Py_XDECREF(ucvt);
+ return NULL;
+ }
errorcb = internal_error_callback(errors);
if (errorcb == NULL) {
@@ -627,7 +637,7 @@ MultibyteCodec_Decode(MultibyteCodecObject *self,
if (datalen == 0) {
PyBuffer_Release(&pdata);
ERROR_DECREF(errorcb);
- return make_tuple(PyUnicode_FromUnicode(NULL, 0), 0);
+ return make_tuple(PyUnicode_New(0, 0), 0);
}
buf.excobj = NULL;
@@ -637,6 +647,8 @@ MultibyteCodec_Decode(MultibyteCodecObject *self,
if (buf.outobj == NULL)
goto errorexit;
buf.outbuf = PyUnicode_AS_UNICODE(buf.outobj);
+ if (buf.outbuf == NULL)
+ goto errorexit;
buf.outbuf_end = buf.outbuf + PyUnicode_GET_SIZE(buf.outobj);
if (self->codec->decinit != NULL &&
@@ -742,6 +754,7 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx,
PyObject *ucvt, *r = NULL;
Py_UNICODE *inbuf, *inbuf_end, *inbuf_tmp = NULL;
Py_ssize_t datalen, origpending;
+ wchar_t *data;
if (PyUnicode_Check(unistr))
ucvt = NULL;
@@ -751,13 +764,15 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx,
return NULL;
else if (!PyUnicode_Check(unistr)) {
PyErr_SetString(PyExc_TypeError,
- "couldn't convert the object to unicode.");
+ "couldn't convert the object to str.");
Py_DECREF(ucvt);
return NULL;
}
}
- datalen = PyUnicode_GET_SIZE(unistr);
+ data = PyUnicode_AsUnicodeAndSize(unistr, &datalen);
+ if (data == NULL)
+ goto errorexit;
origpending = ctx->pendingsize;
if (origpending > 0) {
@@ -848,7 +863,9 @@ decoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data,
buf->outobj = PyUnicode_FromUnicode(NULL, size);
if (buf->outobj == NULL)
return -1;
- buf->outbuf = PyUnicode_AS_UNICODE(buf->outobj);
+ buf->outbuf = PyUnicode_AsUnicode(buf->outobj);
+ if (buf->outbuf == NULL)
+ return -1;
buf->outbuf_end = buf->outbuf +
PyUnicode_GET_SIZE(buf->outobj);
}
@@ -900,11 +917,17 @@ mbiencoder_encode(MultibyteIncrementalEncoderObject *self,
static PyObject *
mbiencoder_reset(MultibyteIncrementalEncoderObject *self)
{
- if (self->codec->decreset != NULL &&
- self->codec->decreset(&self->state, self->codec->config) != 0)
- return NULL;
+ /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */
+ unsigned char buffer[4], *outbuf;
+ Py_ssize_t r;
+ if (self->codec->encreset != NULL) {
+ outbuf = buffer;
+ r = self->codec->encreset(&self->state, self->codec->config,
+ &outbuf, sizeof(buffer));
+ if (r != 0)
+ return NULL;
+ }
self->pendingsize = 0;
-
Py_RETURN_NONE;
}
@@ -1246,7 +1269,7 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self,
Py_ssize_t rsize, finalsize = 0;
if (sizehint == 0)
- return PyUnicode_FromUnicode(NULL, 0);
+ return PyUnicode_New(0, 0);
buf.outobj = buf.excobj = NULL;
cres = NULL;
@@ -1572,12 +1595,13 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self,
PyObject *unistr)
{
PyObject *str, *wr;
+ _Py_IDENTIFIER(write);
str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0);
if (str == NULL)
return -1;
- wr = PyObject_CallMethod(self->stream, "write", "O", str);
+ wr = _PyObject_CallMethodId(self->stream, &PyId_write, "O", str);
Py_DECREF(str);
if (wr == NULL)
return -1;
@@ -1643,7 +1667,9 @@ mbstreamwriter_reset(MultibyteStreamWriterObject *self)
assert(PyBytes_Check(pwrt));
if (PyBytes_Size(pwrt) > 0) {
PyObject *wr;
- wr = PyObject_CallMethod(self->stream, "write", "O", pwrt);
+ _Py_IDENTIFIER(write);
+
+ wr = _PyObject_CallMethodId(self->stream, &PyId_write, "O", pwrt);
if (wr == NULL) {
Py_DECREF(pwrt);
return NULL;