diff --git a/Modules/Bridge/NumPy/include/itkPyBuffer.hxx b/Modules/Bridge/NumPy/include/itkPyBuffer.hxx index 859c4ddae57..69ba3ec27e0 100644 --- a/Modules/Bridge/NumPy/include/itkPyBuffer.hxx +++ b/Modules/Bridge/NumPy/include/itkPyBuffer.hxx @@ -20,6 +20,7 @@ #include "itkImportImageContainer.h" +#include // For unique_ptr. namespace itk { @@ -56,11 +57,9 @@ PyBuffer::_GetArrayViewFromImage(ImageType * image) len *= numberOfComponents; len *= sizeof(ComponentType); - const int res = PyBuffer_FillInfo(&pyBuffer, nullptr, itkImageBuffer, len, 0, PyBUF_CONTIG); + PyBuffer_FillInfo(&pyBuffer, nullptr, itkImageBuffer, len, 0, PyBUF_CONTIG); PyObject * const memoryView = PyMemoryView_FromBuffer(&pyBuffer); - PyBuffer_Release(&pyBuffer); - return memoryView; } @@ -80,15 +79,15 @@ PyBuffer::_GetImageViewFromArray(PyObject * arr, PyObject * shape, PyObj if (PyObject_GetBuffer(arr, &pyBuffer, PyBUF_ND | PyBUF_ANY_CONTIGUOUS) == -1) { PyErr_SetString(PyExc_RuntimeError, "Cannot get an instance of NumPy array."); - PyBuffer_Release(&pyBuffer); return nullptr; } + [[maybe_unused]] const std::unique_ptr bufferScopeGuard(&pyBuffer, + &PyBuffer_Release); + const Py_ssize_t bufferLength = pyBuffer.len; void * const buffer = pyBuffer.buf; - PyBuffer_Release(&pyBuffer); - PyObject * const shapeseq = PySequence_Fast(shape, "expected sequence"); const unsigned int dimension = PySequence_Size(shape); @@ -109,10 +108,9 @@ PyBuffer::_GetImageViewFromArray(PyObject * arr, PyObject * shape, PyObj } const size_t len = numberOfPixels * numberOfComponents * sizeof(ComponentType); - if (bufferLength != len) + if (bufferLength < 0 || static_cast(bufferLength) != len) { PyErr_SetString(PyExc_RuntimeError, "Size mismatch of image and Buffer."); - PyBuffer_Release(&pyBuffer); SWIG_Py_DECREF(shapeseq); return nullptr; } @@ -153,7 +151,6 @@ PyBuffer::_GetImageViewFromArray(PyObject * arr, PyObject * shape, PyObj output->SetNumberOfComponentsPerPixel(numberOfComponents); SWIG_Py_DECREF(shapeseq); - PyBuffer_Release(&pyBuffer); return output; } diff --git a/Modules/Bridge/NumPy/include/itkPyVectorContainer.hxx b/Modules/Bridge/NumPy/include/itkPyVectorContainer.hxx index 994f259ac8c..51026b9addb 100644 --- a/Modules/Bridge/NumPy/include/itkPyVectorContainer.hxx +++ b/Modules/Bridge/NumPy/include/itkPyVectorContainer.hxx @@ -18,6 +18,7 @@ #ifndef itkPyVectorContainer_hxx #define itkPyVectorContainer_hxx +#include // For unique_ptr. #include namespace itk @@ -42,11 +43,9 @@ PyVectorContainer::_array_view_from_vector_contain Py_ssize_t len = vector->Size(); len *= sizeof(DataType); - const int res = PyBuffer_FillInfo(&pyBuffer, nullptr, vectorBuffer, len, 0, PyBUF_CONTIG); + PyBuffer_FillInfo(&pyBuffer, nullptr, vectorBuffer, len, 0, PyBUF_CONTIG); PyObject * const memoryView = PyMemoryView_FromBuffer(&pyBuffer); - PyBuffer_Release(&pyBuffer); - return memoryView; } @@ -60,10 +59,12 @@ PyVectorContainer::_vector_container_from_array(Py if (PyObject_GetBuffer(arr, &pyBuffer, PyBUF_CONTIG) == -1) { PyErr_SetString(PyExc_RuntimeError, "Cannot get an instance of NumPy array."); - PyBuffer_Release(&pyBuffer); return nullptr; } + [[maybe_unused]] const std::unique_ptr bufferScopeGuard(&pyBuffer, + &PyBuffer_Release); + const Py_ssize_t bufferLength = pyBuffer.len; const void * const buffer = pyBuffer.buf; @@ -75,10 +76,9 @@ PyVectorContainer::_vector_container_from_array(Py const size_t numberOfElements = static_cast(PyInt_AsLong(item)); const size_t len = numberOfElements * sizeof(DataType); - if (bufferLength != len) + if (bufferLength < 0 || static_cast(bufferLength) != len) { PyErr_SetString(PyExc_RuntimeError, "Size mismatch of vector and Buffer."); - PyBuffer_Release(&pyBuffer); return nullptr; } const auto * const data = static_cast(buffer); @@ -88,7 +88,6 @@ PyVectorContainer::_vector_container_from_array(Py { output->SetElement(ii, data[ii]); } - PyBuffer_Release(&pyBuffer); return output; } diff --git a/Modules/Bridge/NumPy/include/itkPyVnl.hxx b/Modules/Bridge/NumPy/include/itkPyVnl.hxx index 4114087fb34..e80ce5a78a1 100644 --- a/Modules/Bridge/NumPy/include/itkPyVnl.hxx +++ b/Modules/Bridge/NumPy/include/itkPyVnl.hxx @@ -18,6 +18,7 @@ #ifndef itkPyVnl_hxx #define itkPyVnl_hxx +#include // For unique_ptr. #include namespace itk @@ -42,11 +43,9 @@ PyVnl::_GetArrayViewFromVnlVector(VectorType * vector) Py_ssize_t len = vector->size(); len *= sizeof(DataType); - const int res = PyBuffer_FillInfo(&pyBuffer, nullptr, vectorBuffer, len, 0, PyBUF_CONTIG); + PyBuffer_FillInfo(&pyBuffer, nullptr, vectorBuffer, len, 0, PyBUF_CONTIG); PyObject * const memoryView = PyMemoryView_FromBuffer(&pyBuffer); - PyBuffer_Release(&pyBuffer); - return memoryView; } @@ -59,10 +58,12 @@ PyVnl::_GetVnlVectorFromArray(PyObject * arr, PyObject * shape) -> con if (PyObject_GetBuffer(arr, &pyBuffer, PyBUF_CONTIG) == -1) { PyErr_SetString(PyExc_RuntimeError, "Cannot get an instance of NumPy array."); - PyBuffer_Release(&pyBuffer); return VectorType(); } + [[maybe_unused]] const std::unique_ptr bufferScopeGuard(&pyBuffer, + &PyBuffer_Release); + const Py_ssize_t bufferLength = pyBuffer.len; const void * const buffer = pyBuffer.buf; @@ -74,15 +75,13 @@ PyVnl::_GetVnlVectorFromArray(PyObject * arr, PyObject * shape) -> con const size_t numberOfElements = static_cast(PyInt_AsLong(item)); const size_t len = numberOfElements * sizeof(DataType); - if (bufferLength != len) + if (bufferLength < 0 || static_cast(bufferLength) != len) { PyErr_SetString(PyExc_RuntimeError, "Size mismatch of vector and Buffer."); - PyBuffer_Release(&pyBuffer); return VectorType(); } const auto * const data = static_cast(buffer); VectorType output(data, numberOfElements); - PyBuffer_Release(&pyBuffer); return output; } @@ -106,11 +105,9 @@ PyVnl::_GetArrayViewFromVnlMatrix(MatrixType * matrix) Py_ssize_t len = matrix->size(); len *= sizeof(DataType); - const int res = PyBuffer_FillInfo(&pyBuffer, nullptr, matrixBuffer, len, 0, PyBUF_CONTIG); + PyBuffer_FillInfo(&pyBuffer, nullptr, matrixBuffer, len, 0, PyBUF_CONTIG); PyObject * const memoryView = PyMemoryView_FromBuffer(&pyBuffer); - PyBuffer_Release(&pyBuffer); - return memoryView; } @@ -129,10 +126,12 @@ PyVnl::_GetVnlMatrixFromArray(PyObject * arr, PyObject * shape) -> con if (PyObject_GetBuffer(arr, &pyBuffer, PyBUF_CONTIG) == -1) { PyErr_SetString(PyExc_RuntimeError, "Cannot get an instance of NumPy array."); - PyBuffer_Release(&pyBuffer); return MatrixType(); } + [[maybe_unused]] const std::unique_ptr bufferScopeGuard(&pyBuffer, + &PyBuffer_Release); + const Py_ssize_t bufferLength = pyBuffer.len; const void * const buffer = pyBuffer.buf; @@ -148,16 +147,14 @@ PyVnl::_GetVnlMatrixFromArray(PyObject * arr, PyObject * shape) -> con } const size_t len = numberOfElements * sizeof(DataType); - if (bufferLength != len) + if (bufferLength < 0 || static_cast(bufferLength) != len) { PyErr_SetString(PyExc_RuntimeError, "Size mismatch of matrix and Buffer."); - PyBuffer_Release(&pyBuffer); return MatrixType(); } const auto * const data = static_cast(buffer); MatrixType output(data, size[0], size[1]); - PyBuffer_Release(&pyBuffer); return output; }