From 929dbba834ccbaae1a99c28388e3c223ed9df88f Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Fri, 10 Mar 2023 17:37:06 +1100 Subject: [PATCH 1/7] Handle failure from PyDict_New or PyList_New --- src/_imaging.c | 6 ++++++ src/_imagingft.c | 9 +++++++++ src/_imagingmorph.c | 7 ++++++- src/path.c | 6 ++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/_imaging.c b/src/_imaging.c index 1c25ab00c1d..dc14361f626 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -1249,6 +1249,9 @@ _histogram(ImagingObject *self, PyObject *args) { /* Build an integer list containing the histogram */ list = PyList_New(h->bands * 256); + if (list == NULL) { + return NULL; + } for (i = 0; i < h->bands * 256; i++) { PyObject *item; item = PyLong_FromLong(h->histogram[i]); @@ -2154,6 +2157,9 @@ _getcolors(ImagingObject *self, PyObject *args) { Py_INCREF(out); } else { out = PyList_New(colors); + if (out == NULL) { + return NULL; + } for (i = 0; i < colors; i++) { ImagingColorItem *v = &items[i]; PyObject *item = Py_BuildValue( diff --git a/src/_imagingft.c b/src/_imagingft.c index 0db17a5a6db..3e5244b2f03 100644 --- a/src/_imagingft.c +++ b/src/_imagingft.c @@ -1082,6 +1082,9 @@ font_getvarnames(FontObject *self) { num_namedstyles = master->num_namedstyles; list_names = PyList_New(num_namedstyles); + if (list_names == NULL) { + return NULL; + } name_count = FT_Get_Sfnt_Name_Count(self->face); for (i = 0; i < name_count; i++) { @@ -1125,10 +1128,16 @@ font_getvaraxes(FontObject *self) { name_count = FT_Get_Sfnt_Name_Count(self->face); list_axes = PyList_New(num_axis); + if (list_axes == NULL) { + return NULL; + } for (i = 0; i < num_axis; i++) { axis = master->axis[i]; list_axis = PyDict_New(); + if (list_axis == NULL) { + return NULL; + } PyDict_SetItemString( list_axis, "minimum", PyLong_FromLong(axis.minimum / 65536)); PyDict_SetItemString(list_axis, "default", PyLong_FromLong(axis.def / 65536)); diff --git a/src/_imagingmorph.c b/src/_imagingmorph.c index c0644b61609..43b72539df0 100644 --- a/src/_imagingmorph.c +++ b/src/_imagingmorph.c @@ -136,6 +136,9 @@ match(PyObject *self, PyObject *args) { int row_idx, col_idx; UINT8 **inrows; PyObject *ret = PyList_New(0); + if (ret == NULL) { + return NULL; + } if (!PyArg_ParseTuple(args, "On", &py_lut, &i0)) { PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); @@ -213,10 +216,12 @@ get_on_pixels(PyObject *self, PyObject *args) { int row_idx, col_idx; int width, height; PyObject *ret = PyList_New(0); + if (ret == NULL) { + return NULL; + } if (!PyArg_ParseTuple(args, "n", &i0)) { PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); - return NULL; } img = (Imaging)i0; diff --git a/src/path.c b/src/path.c index 3e3431575ec..e17580fa227 100644 --- a/src/path.c +++ b/src/path.c @@ -439,6 +439,9 @@ path_tolist(PyPathObject *self, PyObject *args) { if (flat) { list = PyList_New(self->count * 2); + if (list == NULL) { + return NULL; + } for (i = 0; i < self->count * 2; i++) { PyObject *item; item = PyFloat_FromDouble(self->xy[i]); @@ -449,6 +452,9 @@ path_tolist(PyPathObject *self, PyObject *args) { } } else { list = PyList_New(self->count); + if (list == NULL) { + return NULL; + } for (i = 0; i < self->count; i++) { PyObject *item; item = Py_BuildValue("dd", self->xy[i + i], self->xy[i + i + 1]); From b3d782374069d18551d2947008210ab8c53ff072 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sun, 12 Mar 2023 00:11:48 +1100 Subject: [PATCH 2/7] Decrement reference count --- src/_imaging.c | 1 + src/_imagingft.c | 12 ++++++++++++ src/_imagingmorph.c | 5 +++++ src/_imagingtk.c | 6 +++++- src/_webp.c | 1 + 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/_imaging.c b/src/_imaging.c index dc14361f626..3cc94328622 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -4306,6 +4306,7 @@ PyInit__imaging(void) { m = PyModule_Create(&module_def); if (setup_module(m) < 0) { + Py_DECREF(m); return NULL; } diff --git a/src/_imagingft.c b/src/_imagingft.c index 3e5244b2f03..93866ec4da0 100644 --- a/src/_imagingft.c +++ b/src/_imagingft.c @@ -1090,6 +1090,7 @@ font_getvarnames(FontObject *self) { for (i = 0; i < name_count; i++) { error = FT_Get_Sfnt_Name(self->face, i, &name); if (error) { + Py_DECREF(list_names); return geterror(error); } @@ -1136,6 +1137,11 @@ font_getvaraxes(FontObject *self) { list_axis = PyDict_New(); if (list_axis == NULL) { + for (j = 0; j < i; j++) { + list_axis = PyList_GetItem(list_axes, j); + Py_DECREF(list_axis); + } + Py_DECREF(list_axes); return NULL; } PyDict_SetItemString( @@ -1147,6 +1153,12 @@ font_getvaraxes(FontObject *self) { for (j = 0; j < name_count; j++) { error = FT_Get_Sfnt_Name(self->face, j, &name); if (error) { + Py_DECREF(list_axis); + for (j = 0; j < i; j++) { + list_axis = PyList_GetItem(list_axes, j); + Py_DECREF(list_axis); + } + Py_DECREF(list_axes); return geterror(error); } diff --git a/src/_imagingmorph.c b/src/_imagingmorph.c index 43b72539df0..3e0c9172a0a 100644 --- a/src/_imagingmorph.c +++ b/src/_imagingmorph.c @@ -141,11 +141,13 @@ match(PyObject *self, PyObject *args) { } if (!PyArg_ParseTuple(args, "On", &py_lut, &i0)) { + Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); return NULL; } if (!PyBytes_Check(py_lut)) { + Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "The morphology LUT is not a bytes object"); return NULL; } @@ -153,6 +155,7 @@ match(PyObject *self, PyObject *args) { lut_len = PyBytes_Size(py_lut); if (lut_len < LUT_SIZE) { + Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "The morphology LUT has the wrong size"); return NULL; } @@ -161,6 +164,7 @@ match(PyObject *self, PyObject *args) { imgin = (Imaging)i0; if (imgin->type != IMAGING_TYPE_UINT8 || imgin->bands != 1) { + Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "Unsupported image type"); return NULL; } @@ -221,6 +225,7 @@ get_on_pixels(PyObject *self, PyObject *args) { } if (!PyArg_ParseTuple(args, "n", &i0)) { + Py_DECREF(ret); PyErr_SetString(PyExc_RuntimeError, "Argument parsing problem"); return NULL; } diff --git a/src/_imagingtk.c b/src/_imagingtk.c index b9273b0b882..ac6a2313872 100644 --- a/src/_imagingtk.c +++ b/src/_imagingtk.c @@ -58,5 +58,9 @@ PyInit__imagingtk(void) { }; PyObject *m; m = PyModule_Create(&module_def); - return (load_tkinter_funcs() == 0) ? m : NULL; + if (load_tkinter_funcs() != 0) { + Py_DECREF(m); + return NULL;; + } + return m; } diff --git a/src/_webp.c b/src/_webp.c index 493e0709c46..0e38453cb7f 100644 --- a/src/_webp.c +++ b/src/_webp.c @@ -987,6 +987,7 @@ PyInit__webp(void) { m = PyModule_Create(&module_def); if (setup_module(m) < 0) { + Py_DECREF(m); return NULL; } From c7d4d1f75a8cee77641629e5a9bf4408146188a6 Mon Sep 17 00:00:00 2001 From: Andrew Murray <3112309+radarhere@users.noreply.github.com> Date: Sat, 18 Mar 2023 22:47:04 +1100 Subject: [PATCH 3/7] Fixed typo Co-authored-by: Aarni Koskela --- src/_imagingtk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_imagingtk.c b/src/_imagingtk.c index ac6a2313872..efa7fc1b6fa 100644 --- a/src/_imagingtk.c +++ b/src/_imagingtk.c @@ -60,7 +60,7 @@ PyInit__imagingtk(void) { m = PyModule_Create(&module_def); if (load_tkinter_funcs() != 0) { Py_DECREF(m); - return NULL;; + return NULL; } return m; } From dfeed0eb7ea1f6a89921f9a2392c111740884ce3 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 20 Mar 2023 22:44:14 +1100 Subject: [PATCH 4/7] Group decrementing reference counts for previous axes in font_getvaraxes --- src/_imagingft.c | 49 +++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/_imagingft.c b/src/_imagingft.c index 93866ec4da0..bf9a242877c 100644 --- a/src/_imagingft.c +++ b/src/_imagingft.c @@ -1114,7 +1114,7 @@ font_getvarnames(FontObject *self) { static PyObject * font_getvaraxes(FontObject *self) { - int error; + int error, failed = 0; FT_UInt i, j, num_axis, name_count; FT_MM_Var *master; FT_Var_Axis axis; @@ -1137,36 +1137,39 @@ font_getvaraxes(FontObject *self) { list_axis = PyDict_New(); if (list_axis == NULL) { + failed = 1; + } else { + PyDict_SetItemString( + list_axis, "minimum", PyLong_FromLong(axis.minimum / 65536)); + PyDict_SetItemString(list_axis, "default", PyLong_FromLong(axis.def / 65536)); + PyDict_SetItemString( + list_axis, "maximum", PyLong_FromLong(axis.maximum / 65536)); + + for (j = 0; j < name_count; j++) { + error = FT_Get_Sfnt_Name(self->face, j, &name); + if (error) { + Py_DECREF(list_axis); + failed = 1; + break; + } + + if (name.name_id == axis.strid) { + axis_name = Py_BuildValue("y#", name.string, name.string_len); + PyDict_SetItemString(list_axis, "name", axis_name); + break; + } + } + } + if (failed) { for (j = 0; j < i; j++) { list_axis = PyList_GetItem(list_axes, j); Py_DECREF(list_axis); } Py_DECREF(list_axes); - return NULL; - } - PyDict_SetItemString( - list_axis, "minimum", PyLong_FromLong(axis.minimum / 65536)); - PyDict_SetItemString(list_axis, "default", PyLong_FromLong(axis.def / 65536)); - PyDict_SetItemString( - list_axis, "maximum", PyLong_FromLong(axis.maximum / 65536)); - - for (j = 0; j < name_count; j++) { - error = FT_Get_Sfnt_Name(self->face, j, &name); if (error) { - Py_DECREF(list_axis); - for (j = 0; j < i; j++) { - list_axis = PyList_GetItem(list_axes, j); - Py_DECREF(list_axis); - } - Py_DECREF(list_axes); return geterror(error); } - - if (name.name_id == axis.strid) { - axis_name = Py_BuildValue("y#", name.string, name.string_len); - PyDict_SetItemString(list_axis, "name", axis_name); - break; - } + return NULL; } PyList_SetItem(list_axes, i, list_axis); From 0ea1184bcfefd1965670cf6d06ca9d44364460d2 Mon Sep 17 00:00:00 2001 From: Andrew Murray <3112309+radarhere@users.noreply.github.com> Date: Thu, 30 Mar 2023 07:54:01 +1100 Subject: [PATCH 5/7] Free additional variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ondrej Baranovič <3819630+nulano@users.noreply.github.com> --- src/_imaging.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/_imaging.c b/src/_imaging.c index c715c36c2ca..b6a7557ffd5 100644 --- a/src/_imaging.c +++ b/src/_imaging.c @@ -1250,6 +1250,7 @@ _histogram(ImagingObject *self, PyObject *args) { /* Build an integer list containing the histogram */ list = PyList_New(h->bands * 256); if (list == NULL) { + ImagingHistogramDelete(h); return NULL; } for (i = 0; i < h->bands * 256; i++) { @@ -2158,6 +2159,7 @@ _getcolors(ImagingObject *self, PyObject *args) { } else { out = PyList_New(colors); if (out == NULL) { + free(items); return NULL; } for (i = 0; i < colors; i++) { From 7632d8df3642111bd1b20b0863511a2ff6b3a113 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 30 Mar 2023 12:35:07 +1100 Subject: [PATCH 6/7] Do not DECREF individual list items, reverting grouping --- src/_imagingft.c | 59 ++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/src/_imagingft.c b/src/_imagingft.c index 57f765e133d..92cfb1db00d 100644 --- a/src/_imagingft.c +++ b/src/_imagingft.c @@ -1114,7 +1114,7 @@ font_getvarnames(FontObject *self) { static PyObject * font_getvaraxes(FontObject *self) { - int error, failed = 0; + int error; FT_UInt i, j, num_axis, name_count; FT_MM_Var *master; FT_Var_Axis axis; @@ -1137,46 +1137,35 @@ font_getvaraxes(FontObject *self) { list_axis = PyDict_New(); if (list_axis == NULL) { - failed = 1; - } else { - PyObject *minimum = PyLong_FromLong(axis.minimum / 65536); - PyDict_SetItemString(list_axis, "minimum", minimum ? minimum : Py_None); - Py_XDECREF(minimum); + Py_DECREF(list_axes); + return NULL; + } + PyObject *minimum = PyLong_FromLong(axis.minimum / 65536); + PyDict_SetItemString(list_axis, "minimum", minimum ? minimum : Py_None); + Py_XDECREF(minimum); - PyObject *def = PyLong_FromLong(axis.def / 65536); - PyDict_SetItemString(list_axis, "default", def ? def : Py_None); - Py_XDECREF(def); + PyObject *def = PyLong_FromLong(axis.def / 65536); + PyDict_SetItemString(list_axis, "default", def ? def : Py_None); + Py_XDECREF(def); - PyObject *maximum = PyLong_FromLong(axis.maximum / 65536); - PyDict_SetItemString(list_axis, "maximum", maximum ? maximum : Py_None); - Py_XDECREF(maximum); + PyObject *maximum = PyLong_FromLong(axis.maximum / 65536); + PyDict_SetItemString(list_axis, "maximum", maximum ? maximum : Py_None); + Py_XDECREF(maximum); - for (j = 0; j < name_count; j++) { - error = FT_Get_Sfnt_Name(self->face, j, &name); - if (error) { - Py_DECREF(list_axis); - failed = 1; - break; - } - - if (name.name_id == axis.strid) { - axis_name = Py_BuildValue("y#", name.string, name.string_len); - PyDict_SetItemString(list_axis, "name", axis_name ? axis_name : Py_None); - Py_XDECREF(axis_name); - break; - } - } - } - if (failed) { - for (j = 0; j < i; j++) { - list_axis = PyList_GetItem(list_axes, j); - Py_DECREF(list_axis); - } - Py_DECREF(list_axes); + for (j = 0; j < name_count; j++) { + error = FT_Get_Sfnt_Name(self->face, j, &name); if (error) { + Py_DECREF(list_axis); + Py_DECREF(list_axes); return geterror(error); } - return NULL; + + if (name.name_id == axis.strid) { + axis_name = Py_BuildValue("y#", name.string, name.string_len); + PyDict_SetItemString(list_axis, "name", axis_name ? axis_name : Py_None); + Py_XDECREF(axis_name); + break; + } } PyList_SetItem(list_axes, i, list_axis); From 448ab0a68780a32b754eb1edb42b4b45d85491af Mon Sep 17 00:00:00 2001 From: Andrew Murray <3112309+radarhere@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:36:58 +1100 Subject: [PATCH 7/7] Call FT_Done_MM_Var when returning early MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ondrej Baranovič <3819630+nulano@users.noreply.github.com> --- src/_imagingft.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/_imagingft.c b/src/_imagingft.c index 92cfb1db00d..e0c28986570 100644 --- a/src/_imagingft.c +++ b/src/_imagingft.c @@ -1083,6 +1083,7 @@ font_getvarnames(FontObject *self) { num_namedstyles = master->num_namedstyles; list_names = PyList_New(num_namedstyles); if (list_names == NULL) { + FT_Done_MM_Var(library, master); return NULL; } @@ -1091,6 +1092,7 @@ font_getvarnames(FontObject *self) { error = FT_Get_Sfnt_Name(self->face, i, &name); if (error) { Py_DECREF(list_names); + FT_Done_MM_Var(library, master); return geterror(error); } @@ -1130,6 +1132,7 @@ font_getvaraxes(FontObject *self) { list_axes = PyList_New(num_axis); if (list_axes == NULL) { + FT_Done_MM_Var(library, master); return NULL; } for (i = 0; i < num_axis; i++) { @@ -1138,6 +1141,7 @@ font_getvaraxes(FontObject *self) { list_axis = PyDict_New(); if (list_axis == NULL) { Py_DECREF(list_axes); + FT_Done_MM_Var(library, master); return NULL; } PyObject *minimum = PyLong_FromLong(axis.minimum / 65536); @@ -1157,6 +1161,7 @@ font_getvaraxes(FontObject *self) { if (error) { Py_DECREF(list_axis); Py_DECREF(list_axes); + FT_Done_MM_Var(library, master); return geterror(error); }