Merge pull request #8416 from radarhere/compact_within_map

This commit is contained in:
Hugo van Kemenade 2024-10-01 13:55:50 +03:00 committed by GitHub
commit 07389b2f18
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 20 additions and 0 deletions

View File

@ -204,6 +204,17 @@ def test_overflow_segfault() -> None:
x[i] = b"0" * 16 x[i] = b"0" * 16
def test_compact_within_map() -> None:
p = ImagePath.Path([0, 1])
def map_func(x: float, y: float) -> tuple[float, float]:
p.compact()
return 0, 0
with pytest.raises(ValueError):
p.map(map_func)
class Evil: class Evil:
def __init__(self) -> None: def __init__(self) -> None:
self.corrupt = Image.core.path(0x4000000000000000) self.corrupt = Image.core.path(0x4000000000000000)

View File

@ -44,6 +44,7 @@ PyImaging_GetBuffer(PyObject *buffer, Py_buffer *view);
typedef struct { typedef struct {
PyObject_HEAD Py_ssize_t count; PyObject_HEAD Py_ssize_t count;
double *xy; double *xy;
int mapping;
} PyPathObject; } PyPathObject;
static PyTypeObject PyPathType; static PyTypeObject PyPathType;
@ -91,6 +92,7 @@ path_new(Py_ssize_t count, double *xy, int duplicate) {
path->count = count; path->count = count;
path->xy = xy; path->xy = xy;
path->mapping = 0;
return path; return path;
} }
@ -276,6 +278,10 @@ path_compact(PyPathObject *self, PyObject *args) {
double cityblock = 2.0; double cityblock = 2.0;
if (self->mapping) {
PyErr_SetString(PyExc_ValueError, "Path compacted during mapping");
return NULL;
}
if (!PyArg_ParseTuple(args, "|d:compact", &cityblock)) { if (!PyArg_ParseTuple(args, "|d:compact", &cityblock)) {
return NULL; return NULL;
} }
@ -393,11 +399,13 @@ path_map(PyPathObject *self, PyObject *args) {
xy = self->xy; xy = self->xy;
/* apply function to coordinate set */ /* apply function to coordinate set */
self->mapping = 1;
for (i = 0; i < self->count; i++) { for (i = 0; i < self->count; i++) {
double x = xy[i + i]; double x = xy[i + i];
double y = xy[i + i + 1]; double y = xy[i + i + 1];
PyObject *item = PyObject_CallFunction(function, "dd", x, y); PyObject *item = PyObject_CallFunction(function, "dd", x, y);
if (!item || !PyArg_ParseTuple(item, "dd", &x, &y)) { if (!item || !PyArg_ParseTuple(item, "dd", &x, &y)) {
self->mapping = 0;
Py_XDECREF(item); Py_XDECREF(item);
return NULL; return NULL;
} }
@ -405,6 +413,7 @@ path_map(PyPathObject *self, PyObject *args) {
xy[i + i + 1] = y; xy[i + i + 1] = y;
Py_DECREF(item); Py_DECREF(item);
} }
self->mapping = 0;
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;