From 55f5351e3de1834bea55a55fc25d8ba6320ec6e9 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Sat, 25 Jan 2025 15:43:22 +0000 Subject: [PATCH] Test for size, add offset support --- Tests/test_arrow.py | 8 ++++++++ src/libImaging/Storage.c | 24 ++++++++---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Tests/test_arrow.py b/Tests/test_arrow.py index fa39275c6..5d7d3cdb5 100644 --- a/Tests/test_arrow.py +++ b/Tests/test_arrow.py @@ -89,6 +89,14 @@ def test_invalid_array_type(mode: str, dest_modes: List[str]) -> None: with pytest.raises(ValueError): Image.fromarrow(img, dest_mode, img.size) +def test_invalid_array_size(): + img = hopper('RGB') + + assert img.size != (10,10) + with pytest.raises(ValueError): + Image.fromarrow(img, 'RGB', (10,10)) + + def test_lifetime(): # valgrind shouldn't error out here. # arrays should be accessible after the image is deleted. diff --git a/src/libImaging/Storage.c b/src/libImaging/Storage.c index c49949d71..701e89cef 100644 --- a/src/libImaging/Storage.c +++ b/src/libImaging/Storage.c @@ -571,34 +571,26 @@ ImagingDestroyArrow(Imaging im) { } Imaging -ImagingAllocateArrow(Imaging im, struct ArrowArray *external_array) { - /* don't really allocate, but naming patterns */ +ImagingBorrowArrow(Imaging im, + struct ArrowArray *external_array, + int offset_width) { + // offset_width is the # of char* for a single offset from arrow Py_ssize_t y, i; char *borrowed_buffer = NULL; struct ArrowArray *arr = external_array; - /* overflow check for malloc */ - if (im->linesize && im->ysize > INT_MAX / im->linesize) { - return (Imaging)ImagingError_MemoryError(); - } - if (arr->n_children == 1) { arr = arr->children[0]; } if (arr->n_buffers == 2) { - // undone offset. offset here is # of elements, - // so depends on the size of the element - // undone image is char*, arrow is void * // buffer 0 is the null list // buffer 1 is the data - borrowed_buffer = (char *)arr->buffers[1]; + borrowed_buffer = (char *)arr->buffers[1] + (offset_width*arr->offset); } if (!borrowed_buffer) { - // UNDONE better error here. - // currently, only wanting one where - return (Imaging)ImagingError_MemoryError(); + return (Imaging)ImagingError_ValueError("Arrow Array, exactly 2 buffers required"); } for (y = i = 0; y < im->ysize; y++) { @@ -714,7 +706,7 @@ ImagingNewArrow( && im->bands == 1)) // Single band match && pixels == external_array->length) { // one arrow element per, and it matches a pixelsize*char - if (ImagingAllocateArrow(im, external_array)) { + if (ImagingBorrowArrow(im, external_array, im->pixelsize)) { return im; } } @@ -730,7 +722,7 @@ ImagingNewArrow( && external_array->children // array is well formed && 4 * pixels == external_array->children[0]->length) { // 4 up element of char into pixelsize == 4 - if (ImagingAllocateArrow(im, external_array)) { + if (ImagingBorrowArrow(im, external_array, 1)) { return im; } }