Reject non-numeric elements inside list coords (#9526)
This commit is contained in:
parent
ffdcede651
commit
cf6de8ca9b
@ -51,6 +51,7 @@ def test_path() -> None:
|
||||
[0.0, 1.0],
|
||||
((0, 1),),
|
||||
[(0, 1)],
|
||||
[[0, 1]],
|
||||
((0.0, 1.0),),
|
||||
[(0.0, 1.0)],
|
||||
array.array("f", [0, 1]),
|
||||
@ -68,6 +69,34 @@ def test_path_constructors(
|
||||
assert list(p) == [(0.0, 1.0)]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"coords, expected",
|
||||
(
|
||||
([[0, 1], [2, 3]], [(0.0, 1.0), (2.0, 3.0)]),
|
||||
([[0.0, 1.0], [2.0, 3.0]], [(0.0, 1.0), (2.0, 3.0)]),
|
||||
),
|
||||
)
|
||||
def test_path_list_of_lists(
|
||||
coords: list[list[float]], expected: list[tuple[float, float]]
|
||||
) -> None:
|
||||
p = ImagePath.Path(coords)
|
||||
assert list(p) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"coords, message",
|
||||
(
|
||||
([[1, 2, 3]], "coordinate list must contain exactly 2 coordinates"),
|
||||
([[1]], "coordinate list must contain exactly 2 coordinates"),
|
||||
([[[1, 2], [3, 4]]], "coordinate list must contain numbers"),
|
||||
([["a", "b"]], "coordinate list must contain numbers"),
|
||||
),
|
||||
)
|
||||
def test_invalid_list_coords(coords: list[list[object]], message: str) -> None:
|
||||
with pytest.raises(ValueError, match=message):
|
||||
ImagePath.Path(coords)
|
||||
|
||||
|
||||
def test_invalid_path_constructors() -> None:
|
||||
# Arrange / Act
|
||||
with pytest.raises(ValueError, match="incorrect coordinate type"):
|
||||
|
||||
@ -33,6 +33,16 @@ Integer overflow when processing fonts
|
||||
If a font advances for each glyph by an exceeding large amount, when Pillow keeps track
|
||||
of the current position, it may lead to an integer overflow. This has been fixed.
|
||||
|
||||
Heap buffer overflow with nested list coordinates
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Passing nested lists as coordinates to APIs that accept coordinates such as
|
||||
``ImagePath.Path``, :py:meth:`~PIL.ImageDraw.ImageDraw.polygon`
|
||||
and :py:meth:`~PIL.ImageDraw.ImageDraw.line` could cause a heap buffer overflow,
|
||||
as nested lists were recursively unpacked beyond the allocated buffer.
|
||||
Coordinate lists are now validated to contain exactly two numeric coordinates.
|
||||
This was introduced in Pillow 11.2.1.
|
||||
|
||||
API changes
|
||||
===========
|
||||
|
||||
|
||||
15
src/path.c
15
src/path.c
@ -118,14 +118,27 @@ assign_item_to_array(double *xy, Py_ssize_t j, PyObject *op) {
|
||||
} else if (PyNumber_Check(op)) {
|
||||
xy[j++] = PyFloat_AsDouble(op);
|
||||
} else if (PyList_Check(op)) {
|
||||
if (PyList_GET_SIZE(op) != 2) {
|
||||
PyErr_SetString(
|
||||
PyExc_ValueError, "coordinate list must contain exactly 2 coordinates"
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
for (int k = 0; k < 2; k++) {
|
||||
PyObject *op1 = PyList_GetItemRef(op, k);
|
||||
if (op1 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
j = assign_item_to_array(xy, j, op1);
|
||||
if (PyFloat_Check(op1) || PyLong_Check(op1) || PyNumber_Check(op1)) {
|
||||
j = assign_item_to_array(xy, j, op1);
|
||||
} else {
|
||||
j = -1;
|
||||
}
|
||||
Py_DECREF(op1);
|
||||
if (j == -1) {
|
||||
PyErr_SetString(
|
||||
PyExc_ValueError, "coordinate list must contain numbers"
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user