From e53d71c2d63351ad31fea6b1101a2f43c5e7a3d5 Mon Sep 17 00:00:00 2001 From: Ricci Adams Date: Tue, 1 Sep 2026 09:33:11 -0700 Subject: [PATCH] Check for null result after calling ensure() --- lib/matplotlib/tests/test_lines.py | 6 ++++++ lib/matplotlib/tests/test_transforms.py | 25 +++++++++++++++++++++++++ src/_image_wrapper.cpp | 3 +++ src/_path_wrapper.cpp | 5 ++++- src/py_converters.h | 5 +++-- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/tests/test_lines.py b/lib/matplotlib/tests/test_lines.py index 54e515449bd1..1a1f37c9b1e1 100644 --- a/lib/matplotlib/tests/test_lines.py +++ b/lib/matplotlib/tests/test_lines.py @@ -203,6 +203,12 @@ def test_lw_scaling(): def test_is_sorted_and_has_non_nan(): + with pytest.raises(ValueError): + _path.is_sorted_and_has_non_nan(None) + with pytest.raises(ValueError): + _path.is_sorted_and_has_non_nan([[[[None]], None]]) + with pytest.raises(ValueError): + print(_path.is_sorted_and_has_non_nan([""])) assert _path.is_sorted_and_has_non_nan(np.array([1, 2, 3])) assert _path.is_sorted_and_has_non_nan(np.array([1, np.nan, 3])) assert not _path.is_sorted_and_has_non_nan([3, 5] + [np.nan] * 100 + [0, 2]) diff --git a/lib/matplotlib/tests/test_transforms.py b/lib/matplotlib/tests/test_transforms.py index d869240adaec..098635a6c7dc 100644 --- a/lib/matplotlib/tests/test_transforms.py +++ b/lib/matplotlib/tests/test_transforms.py @@ -11,6 +11,7 @@ import matplotlib.transforms as mtransforms from matplotlib.transforms import Affine2D, Bbox, TransformedBbox, _ScaledRotation from matplotlib.path import Path +from matplotlib._path import count_bboxes_overlapping_bbox from matplotlib.testing.decorators import image_comparison, check_figures_equal from unittest.mock import MagicMock @@ -900,6 +901,30 @@ def test_bbox_as_strings(): assert eval(format(getattr(b, k), fmt)) == v +def test_count_bboxes_overlapping_bbox(): + for invalid_bbox in [ + [[[[None]], None]], + [1, 2, 3], + [], + [[1], [2]], + ]: + with pytest.raises(ValueError): + count_bboxes_overlapping_bbox(invalid_bbox, None) + + corners = ( + [[0, 0], [2, 2]], + [[8, 0], [10, 2]], + [[0, 8], [2, 10]], + [[8, 8], [10, 10]], + ) + center = [[4, 4], [6, 6]] + bbox = [[0, 0], [10, 10]] + + assert count_bboxes_overlapping_bbox(bbox, corners) == 4 + assert count_bboxes_overlapping_bbox(bbox, (center, )) == 1 + assert count_bboxes_overlapping_bbox(bbox, (center, *corners)) == 5 + + def test_str_transform(): # The str here should not be considered as "absolutely stable", and may be # reformatted later; this is just a smoketest for __str__. diff --git a/src/_image_wrapper.cpp b/src/_image_wrapper.cpp index c151af9e92ea..d7edf6b93c08 100644 --- a/src/_image_wrapper.cpp +++ b/src/_image_wrapper.cpp @@ -131,6 +131,9 @@ image_resample(py::array input_array, // Ensure input array is contiguous, regardless of dtype input_array = py::array::ensure(input_array, py::array::c_style); + if (!input_array) { + throw std::invalid_argument("Input array could not be made C-contiguous"); + } // Validate output array auto out_ndim = output_array.ndim(); diff --git a/src/_path_wrapper.cpp b/src/_path_wrapper.cpp index d0e02151429c..4f9591060a9f 100644 --- a/src/_path_wrapper.cpp +++ b/src/_path_wrapper.cpp @@ -284,7 +284,7 @@ Py_is_sorted_and_has_non_nan(py::object obj) bool result; py::array array = py::array::ensure(obj); - if (array.ndim() != 1) { + if (!array || array.ndim() != 1) { throw std::invalid_argument("array must be 1D"); } @@ -300,6 +300,9 @@ Py_is_sorted_and_has_non_nan(py::object obj) result = is_sorted_and_has_non_nan(array); } else { array = py::array_t::ensure(obj); + if (!array) { + throw std::invalid_argument("Could not coerce array to double"); + } result = is_sorted_and_has_non_nan(array); } diff --git a/src/py_converters.h b/src/py_converters.h index c03df3933ed8..d354eab701dc 100644 --- a/src/py_converters.h +++ b/src/py_converters.h @@ -60,8 +60,9 @@ namespace PYBIND11_NAMESPACE { namespace detail { } auto rect_arr = py::array_t::ensure(src); + auto ndim = rect_arr ? rect_arr.ndim() : 0; - if (rect_arr.ndim() == 2) { + if (ndim == 2) { if (rect_arr.shape(0) != 2 || rect_arr.shape(1) != 2) { throw py::value_error("Invalid bounding box"); } @@ -71,7 +72,7 @@ namespace PYBIND11_NAMESPACE { namespace detail { value.x2 = *rect_arr.data(1, 0); value.y2 = *rect_arr.data(1, 1); - } else if (rect_arr.ndim() == 1) { + } else if (ndim == 1) { if (rect_arr.shape(0) != 4) { throw py::value_error("Invalid bounding box"); }