Fix refcounts after porting to GetItemRef & better error checking (#126)

This commit is contained in:
Hugo van Kemenade 2024-07-13 12:41:39 +02:00 committed by GitHub
commit 851868c775
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 12 deletions

View File

@ -2251,6 +2251,11 @@ _getcolors(ImagingObject *self, PyObject *args) {
ImagingColorItem *v = &items[i]; ImagingColorItem *v = &items[i];
PyObject *item = Py_BuildValue( PyObject *item = Py_BuildValue(
"iN", v->count, getpixel(self->image, self->access, v->x, v->y)); "iN", v->count, getpixel(self->image, self->access, v->x, v->y));
if (item == NULL) {
Py_DECREF(out);
free(items);
return NULL;
}
PyList_SetItem(out, i, item); PyList_SetItem(out, i, item);
} }
} }

View File

@ -1205,9 +1205,15 @@ font_getvarnames(FontObject *self) {
num_namedstyles = master->num_namedstyles; num_namedstyles = master->num_namedstyles;
list_names = PyList_New(num_namedstyles); list_names = PyList_New(num_namedstyles);
if (list_names == NULL) {
FT_Done_MM_Var(library, master);
return NULL;
}
int *list_names_filled = PyMem_Malloc(num_namedstyles * sizeof(int)); int *list_names_filled = PyMem_Malloc(num_namedstyles * sizeof(int));
if (list_names_filled == NULL) { if (list_names_filled == NULL) {
Py_DECREF(list_names);
FT_Done_MM_Var(library, master);
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
@ -1215,15 +1221,11 @@ font_getvarnames(FontObject *self) {
list_names_filled[i] = 0; list_names_filled[i] = 0;
} }
if (list_names == NULL) {
FT_Done_MM_Var(library, master);
return NULL;
}
name_count = FT_Get_Sfnt_Name_Count(self->face); name_count = FT_Get_Sfnt_Name_Count(self->face);
for (i = 0; i < name_count; i++) { for (i = 0; i < name_count; i++) {
error = FT_Get_Sfnt_Name(self->face, i, &name); error = FT_Get_Sfnt_Name(self->face, i, &name);
if (error) { if (error) {
PyMem_Free(list_names_filled);
Py_DECREF(list_names); Py_DECREF(list_names);
FT_Done_MM_Var(library, master); FT_Done_MM_Var(library, master);
return geterror(error); return geterror(error);
@ -1236,6 +1238,12 @@ font_getvarnames(FontObject *self) {
if (master->namedstyle[j].strid == name.name_id) { if (master->namedstyle[j].strid == name.name_id) {
list_name = Py_BuildValue("y#", name.string, name.string_len); list_name = Py_BuildValue("y#", name.string, name.string_len);
if (list_name == NULL) {
PyMem_Free(list_names_filled);
Py_DECREF(list_names);
FT_Done_MM_Var(library, master);
return NULL;
}
PyList_SetItem(list_names, j, list_name); PyList_SetItem(list_names, j, list_name);
list_names_filled[j] = 1; list_names_filled[j] = 1;
break; break;
@ -1301,9 +1309,15 @@ font_getvaraxes(FontObject *self) {
if (name.name_id == axis.strid) { if (name.name_id == axis.strid) {
axis_name = Py_BuildValue("y#", name.string, name.string_len); axis_name = Py_BuildValue("y#", name.string, name.string_len);
if (axis_name == NULL) {
Py_DECREF(list_axis);
Py_DECREF(list_axes);
FT_Done_MM_Var(library, master);
return NULL;
}
PyDict_SetItemString( PyDict_SetItemString(
list_axis, "name", axis_name ? axis_name : Py_None); list_axis, "name", axis_name ? axis_name : Py_None);
Py_XDECREF(axis_name); Py_DECREF(axis_name);
break; break;
} }
} }
@ -1357,7 +1371,12 @@ font_setvaraxes(FontObject *self, PyObject *args) {
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
for (i = 0; i < num_coords; i++) { for (i = 0; i < num_coords; i++) {
item = PyList_GET_ITEM(axes, i); item = PyList_GetItemRef(axes, i);
if (item == NULL) {
free(coords);
return NULL;
}
if (PyFloat_Check(item)) { if (PyFloat_Check(item)) {
coord = PyFloat_AS_DOUBLE(item); coord = PyFloat_AS_DOUBLE(item);
} else if (PyLong_Check(item)) { } else if (PyLong_Check(item)) {
@ -1365,10 +1384,12 @@ font_setvaraxes(FontObject *self, PyObject *args) {
} else if (PyNumber_Check(item)) { } else if (PyNumber_Check(item)) {
coord = PyFloat_AsDouble(item); coord = PyFloat_AsDouble(item);
} else { } else {
Py_DECREF(item);
free(coords); free(coords);
PyErr_SetString(PyExc_TypeError, "list must contain numbers"); PyErr_SetString(PyExc_TypeError, "list must contain numbers");
return NULL; return NULL;
} }
Py_DECREF(item);
coords[i] = coord * 65536; coords[i] = coord * 65536;
} }

View File

@ -673,10 +673,16 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
TRACE(("tags size: %d\n", (int)tags_size)); TRACE(("tags size: %d\n", (int)tags_size));
for (pos = 0; pos < tags_size; pos++) { for (pos = 0; pos < tags_size; pos++) {
item = PyList_GetItemRef(tags, pos); item = PyList_GetItemRef(tags, pos);
if (item == NULL) {
return NULL;
}
if (!PyTuple_Check(item) || PyTuple_Size(item) != 2) { if (!PyTuple_Check(item) || PyTuple_Size(item) != 2) {
Py_DECREF(item);
PyErr_SetString(PyExc_ValueError, "Invalid tags list"); PyErr_SetString(PyExc_ValueError, "Invalid tags list");
return NULL; return NULL;
} }
Py_DECREF(item);
} }
pos = 0; pos = 0;
} }
@ -705,10 +711,16 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
num_core_tags = sizeof(core_tags) / sizeof(int); num_core_tags = sizeof(core_tags) / sizeof(int);
for (pos = 0; pos < tags_size; pos++) { for (pos = 0; pos < tags_size; pos++) {
item = PyList_GetItemRef(tags, pos); item = PyList_GetItemRef(tags, pos);
if (item == NULL) {
return NULL;
}
// We already checked that tags is a 2-tuple list. // We already checked that tags is a 2-tuple list.
key = PyTuple_GetItem(item, 0); key = PyTuple_GET_ITEM(item, 0);
key_int = (int)PyLong_AsLong(key); key_int = (int)PyLong_AsLong(key);
value = PyTuple_GetItem(item, 1); value = PyTuple_GET_ITEM(item, 1);
Py_DECREF(item);
status = 0; status = 0;
is_core_tag = 0; is_core_tag = 0;
is_var_length = 0; is_var_length = 0;

View File

@ -26,6 +26,7 @@
*/ */
#include "Python.h" #include "Python.h"
#include "thirdparty/pythoncapi_compat.h"
#include "libImaging/Imaging.h" #include "libImaging/Imaging.h"
#include <math.h> #include <math.h>
@ -179,14 +180,21 @@ PyPath_Flatten(PyObject *data, double **pxy) {
} \ } \
free(xy); \ free(xy); \
return -1; \ return -1; \
} \
if (decref) { \
Py_DECREF(op); \
} }
/* Copy table to path array */ /* Copy table to path array */
if (PyList_Check(data)) { if (PyList_Check(data)) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
double x, y; double x, y;
PyObject *op = PyList_GET_ITEM(data, i); PyObject *op = PyList_GetItemRef(data, i);
assign_item_to_array(op, 0); if (op == NULL) {
free(xy);
return -1;
}
assign_item_to_array(op, 1);
} }
} else if (PyTuple_Check(data)) { } else if (PyTuple_Check(data)) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
@ -209,7 +217,6 @@ PyPath_Flatten(PyObject *data, double **pxy) {
} }
} }
assign_item_to_array(op, 1); assign_item_to_array(op, 1);
Py_DECREF(op);
} }
} }