From b9c03e999f74ef87f72b6aea8c68618b1e93545b Mon Sep 17 00:00:00 2001 From: Hye-Shik Chang Date: Mon, 27 Mar 2006 08:24:54 +0000 Subject: [PATCH] Fix reference leaks introduced by the recent incremental codec changes. --- Modules/cjkcodecs/multibytecodec.c | 85 +++++++++++++++++------------- Modules/cjkcodecs/multibytecodec.h | 8 +-- 2 files changed, 52 insertions(+), 41 deletions(-) diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 6e5c5878143..73689ef8e4b 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -758,7 +758,9 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, datalen, ctx->errors, final ? MBENC_FLUSH : 0); if (r == NULL) { /* recover the original pending buffer */ - memcpy(ctx->pending, inbuf_tmp, Py_UNICODE_SIZE * origpending); + if (origpending > 0) + memcpy(ctx->pending, inbuf_tmp, + Py_UNICODE_SIZE * origpending); ctx->pendingsize = origpending; goto errorexit; } @@ -887,17 +889,9 @@ static PyObject * mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { MultibyteIncrementalEncoderObject *self; - PyObject *codec; + PyObject *codec = NULL; char *errors = NULL; - codec = PyObject_GetAttrString((PyObject *)type, "codec"); - if (codec == NULL) - return NULL; - if (!MultibyteCodec_Check(codec)) { - PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); - return NULL; - } - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder", incnewkwarglist, &errors)) return NULL; @@ -906,6 +900,14 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self == NULL) return NULL; + codec = PyObject_GetAttrString((PyObject *)type, "codec"); + if (codec == NULL) + goto errorexit; + if (!MultibyteCodec_Check(codec)) { + PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + goto errorexit; + } + self->codec = ((MultibyteCodecObject *)codec)->codec; self->pendingsize = 0; self->errors = internal_error_callback(errors); @@ -915,10 +917,12 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->codec->encinit(&self->state, self->codec->config) != 0) goto errorexit; + Py_DECREF(codec); return (PyObject *)self; errorexit: Py_XDECREF(self); + Py_XDECREF(codec); return NULL; } @@ -1080,17 +1084,9 @@ static PyObject * mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { MultibyteIncrementalDecoderObject *self; - PyObject *codec; + PyObject *codec = NULL; char *errors = NULL; - codec = PyObject_GetAttrString((PyObject *)type, "codec"); - if (codec == NULL) - return NULL; - if (!MultibyteCodec_Check(codec)) { - PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); - return NULL; - } - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder", incnewkwarglist, &errors)) return NULL; @@ -1099,6 +1095,14 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self == NULL) return NULL; + codec = PyObject_GetAttrString((PyObject *)type, "codec"); + if (codec == NULL) + goto errorexit; + if (!MultibyteCodec_Check(codec)) { + PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + goto errorexit; + } + self->codec = ((MultibyteCodecObject *)codec)->codec; self->pendingsize = 0; self->errors = internal_error_callback(errors); @@ -1108,10 +1112,12 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->codec->decinit(&self->state, self->codec->config) != 0) goto errorexit; + Py_DECREF(codec); return (PyObject *)self; errorexit: Py_XDECREF(self); + Py_XDECREF(codec); return NULL; } @@ -1381,17 +1387,9 @@ static PyObject * mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { MultibyteStreamReaderObject *self; - PyObject *codec, *stream; + PyObject *stream, *codec = NULL; char *errors = NULL; - codec = PyObject_GetAttrString((PyObject *)type, "codec"); - if (codec == NULL) - return NULL; - if (!MultibyteCodec_Check(codec)) { - PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); - return NULL; - } - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader", streamkwarglist, &stream, &errors)) return NULL; @@ -1400,6 +1398,14 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self == NULL) return NULL; + codec = PyObject_GetAttrString((PyObject *)type, "codec"); + if (codec == NULL) + goto errorexit; + if (!MultibyteCodec_Check(codec)) { + PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + goto errorexit; + } + self->codec = ((MultibyteCodecObject *)codec)->codec; self->stream = stream; Py_INCREF(stream); @@ -1411,10 +1417,12 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->codec->decinit(&self->state, self->codec->config) != 0) goto errorexit; + Py_DECREF(codec); return (PyObject *)self; errorexit: Py_XDECREF(self); + Py_XDECREF(codec); return NULL; } @@ -1501,6 +1509,7 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, if (wr == NULL) return -1; + Py_DECREF(wr); return 0; } @@ -1583,17 +1592,9 @@ static PyObject * mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { MultibyteStreamWriterObject *self; - PyObject *codec, *stream; + PyObject *stream, *codec = NULL; char *errors = NULL; - codec = PyObject_GetAttrString((PyObject *)type, "codec"); - if (codec == NULL) - return NULL; - if (!MultibyteCodec_Check(codec)) { - PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); - return NULL; - } - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter", streamkwarglist, &stream, &errors)) return NULL; @@ -1602,6 +1603,14 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self == NULL) return NULL; + codec = PyObject_GetAttrString((PyObject *)type, "codec"); + if (codec == NULL) + goto errorexit; + if (!MultibyteCodec_Check(codec)) { + PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); + goto errorexit; + } + self->codec = ((MultibyteCodecObject *)codec)->codec; self->stream = stream; Py_INCREF(stream); @@ -1613,10 +1622,12 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->codec->encinit(&self->state, self->codec->config) != 0) goto errorexit; + Py_DECREF(codec); return (PyObject *)self; errorexit: Py_XDECREF(self); + Py_XDECREF(codec); return NULL; } diff --git a/Modules/cjkcodecs/multibytecodec.h b/Modules/cjkcodecs/multibytecodec.h index 671ecaee94e..22ea5d4abfc 100644 --- a/Modules/cjkcodecs/multibytecodec.h +++ b/Modules/cjkcodecs/multibytecodec.h @@ -123,10 +123,10 @@ typedef struct { #define ERROR_IGNORE (PyObject *)(2) #define ERROR_REPLACE (PyObject *)(3) #define ERROR_ISCUSTOM(p) ((p) < ERROR_STRICT || ERROR_REPLACE < (p)) -#define ERROR_DECREF(p) do { \ - if (ERROR_ISCUSTOM(p)) { \ - Py_DECREF(p); \ - } \ +#define ERROR_DECREF(p) do { \ + if (p != NULL && ERROR_ISCUSTOM(p)) { \ + Py_DECREF(p); \ + } \ } while (0); #define MBENC_FLUSH 0x0001 /* encode all characters encodable */