Skip to content

Commit 38473ac

Browse files
Don't copy input buffer data
Using PyMemoryView_GetContiguous was risky as a non-contiguous input would get copied. Using PyMemoryView_FromObject and checking the result avoids any unwanted copying.
1 parent 0f2f0aa commit 38473ac

11 files changed

Lines changed: 783 additions & 391 deletions

File tree

src/interface/shared/buffers.i

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@ _HOLD_BUFFER(remainder)
3030
%define INPUT_BUFFER_RO(buf_type, len_type, hold_funcs...)
3131
%typemap(doctype) buf_type ":py:term:`bytes-like object`";
3232
%typemap(in) (buf_type, len_type) (PyObject* _global_view = NULL) {
33-
_global_view = PyMemoryView_GetContiguous($input, PyBUF_READ, 'A');
34-
if (!_global_view) {
33+
Py_buffer* buff = NULL;
34+
_global_view = PyMemoryView_FromObject($input);
35+
if (_global_view)
36+
buff = PyMemoryView_GET_BUFFER(_global_view);
37+
else
3538
PyErr_Clear();
39+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
40+
|| (buff->shape && buff->itemsize != 1)) {
3641
%argument_fail(
3742
SWIG_TypeError, "bytes-like object", $symname, $argnum);
3843
}
39-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
4044
$1 = ($1_ltype) buff->buf;
4145
$2 = ($2_ltype) buff->len;
4246
}

src/swig-0_27_7/basicio_wrap.cxx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5026,13 +5026,17 @@ SWIGINTERN PyObject *_wrap_BasicIo_write__SWIG_0(PyObject *self, PyObject *args)
50265026
}
50275027
arg1 = reinterpret_cast< Exiv2::BasicIo * >(argp1);
50285028
{
5029-
_global_view = PyMemoryView_GetContiguous(obj1, PyBUF_READ, 'A');
5030-
if (!_global_view) {
5031-
PyErr_Clear();
5029+
Py_buffer* buff = NULL;
5030+
_global_view = PyMemoryView_FromObject(obj1);
5031+
if (_global_view)
5032+
buff = PyMemoryView_GET_BUFFER(_global_view);
5033+
else
5034+
PyErr_Clear();
5035+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
5036+
|| (buff->shape && buff->itemsize != 1)) {
50325037
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "BasicIo_write" "', argument " "2"" of type '" "bytes-like object""'")
50335038
;
50345039
}
5035-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
50365040
arg2 = (Exiv2::byte *) buff->buf;
50375041
arg3 = (long) buff->len;
50385042
}

src/swig-0_27_7/exif_wrap.cxx

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6067,13 +6067,17 @@ SWIGINTERN PyObject *_wrap_ExifData_iterator_setDataArea(PyObject *self, PyObjec
60676067
}
60686068
arg1 = reinterpret_cast< ExifData_iterator * >(argp1);
60696069
{
6070-
_global_view = PyMemoryView_GetContiguous(obj1, PyBUF_READ, 'A');
6071-
if (!_global_view) {
6072-
PyErr_Clear();
6070+
Py_buffer* buff = NULL;
6071+
_global_view = PyMemoryView_FromObject(obj1);
6072+
if (_global_view)
6073+
buff = PyMemoryView_GET_BUFFER(_global_view);
6074+
else
6075+
PyErr_Clear();
6076+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
6077+
|| (buff->shape && buff->itemsize != 1)) {
60736078
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ExifData_iterator_setDataArea" "', argument " "2"" of type '" "bytes-like object""'")
60746079
;
60756080
}
6076-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
60776081
arg2 = (Exiv2::byte *) buff->buf;
60786082
arg3 = (long) buff->len;
60796083
}
@@ -7534,13 +7538,17 @@ SWIGINTERN PyObject *_wrap_Exifdatum_setDataArea(PyObject *self, PyObject *args)
75347538
}
75357539
arg1 = reinterpret_cast< Exiv2::Exifdatum * >(argp1);
75367540
{
7537-
_global_view = PyMemoryView_GetContiguous(obj1, PyBUF_READ, 'A');
7538-
if (!_global_view) {
7539-
PyErr_Clear();
7541+
Py_buffer* buff = NULL;
7542+
_global_view = PyMemoryView_FromObject(obj1);
7543+
if (_global_view)
7544+
buff = PyMemoryView_GET_BUFFER(_global_view);
7545+
else
7546+
PyErr_Clear();
7547+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
7548+
|| (buff->shape && buff->itemsize != 1)) {
75407549
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "Exifdatum_setDataArea" "', argument " "2"" of type '" "bytes-like object""'")
75417550
;
75427551
}
7543-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
75447552
arg2 = (Exiv2::byte *) buff->buf;
75457553
arg3 = (long) buff->len;
75467554
}
@@ -9118,13 +9126,17 @@ SWIGINTERN PyObject *_wrap_ExifThumb_setJpegThumbnail__SWIG_1(PyObject *self, Py
91189126
}
91199127
arg1 = reinterpret_cast< Exiv2::ExifThumb * >(argp1);
91209128
{
9121-
_global_view = PyMemoryView_GetContiguous(obj1, PyBUF_READ, 'A');
9122-
if (!_global_view) {
9123-
PyErr_Clear();
9129+
Py_buffer* buff = NULL;
9130+
_global_view = PyMemoryView_FromObject(obj1);
9131+
if (_global_view)
9132+
buff = PyMemoryView_GET_BUFFER(_global_view);
9133+
else
9134+
PyErr_Clear();
9135+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
9136+
|| (buff->shape && buff->itemsize != 1)) {
91249137
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ExifThumb_setJpegThumbnail" "', argument " "2"" of type '" "bytes-like object""'")
91259138
;
91269139
}
9127-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
91289140
arg2 = (Exiv2::byte *) buff->buf;
91299141
arg3 = (long) buff->len;
91309142
}
@@ -9247,13 +9259,17 @@ SWIGINTERN PyObject *_wrap_ExifThumb_setJpegThumbnail__SWIG_3(PyObject *self, Py
92479259
}
92489260
arg1 = reinterpret_cast< Exiv2::ExifThumb * >(argp1);
92499261
{
9250-
_global_view = PyMemoryView_GetContiguous(obj1, PyBUF_READ, 'A');
9251-
if (!_global_view) {
9252-
PyErr_Clear();
9262+
Py_buffer* buff = NULL;
9263+
_global_view = PyMemoryView_FromObject(obj1);
9264+
if (_global_view)
9265+
buff = PyMemoryView_GET_BUFFER(_global_view);
9266+
else
9267+
PyErr_Clear();
9268+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
9269+
|| (buff->shape && buff->itemsize != 1)) {
92539270
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ExifThumb_setJpegThumbnail" "', argument " "2"" of type '" "bytes-like object""'")
92549271
;
92559272
}
9256-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
92579273
arg2 = (Exiv2::byte *) buff->buf;
92589274
arg3 = (long) buff->len;
92599275
}

src/swig-0_27_7/image_wrap.cxx

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6513,13 +6513,17 @@ SWIGINTERN PyObject *_wrap_ImageFactory_open__SWIG_1(PyObject *self, Py_ssize_t
65136513

65146514
if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
65156515
{
6516-
_global_view = PyMemoryView_GetContiguous(swig_obj[0], PyBUF_READ, 'A');
6517-
if (!_global_view) {
6518-
PyErr_Clear();
6516+
Py_buffer* buff = NULL;
6517+
_global_view = PyMemoryView_FromObject(swig_obj[0]);
6518+
if (_global_view)
6519+
buff = PyMemoryView_GET_BUFFER(_global_view);
6520+
else
6521+
PyErr_Clear();
6522+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
6523+
|| (buff->shape && buff->itemsize != 1)) {
65196524
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageFactory_open" "', argument " "1"" of type '" "bytes-like object""'")
65206525
;
65216526
}
6522-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
65236527
arg1 = (Exiv2::byte *) buff->buf;
65246528
arg2 = (long) buff->len;
65256529
}
@@ -6786,13 +6790,17 @@ SWIGINTERN PyObject *_wrap_ImageFactory_getType__SWIG_1(PyObject *self, Py_ssize
67866790

67876791
if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
67886792
{
6789-
_global_view = PyMemoryView_GetContiguous(swig_obj[0], PyBUF_READ, 'A');
6790-
if (!_global_view) {
6791-
PyErr_Clear();
6793+
Py_buffer* buff = NULL;
6794+
_global_view = PyMemoryView_FromObject(swig_obj[0]);
6795+
if (_global_view)
6796+
buff = PyMemoryView_GET_BUFFER(_global_view);
6797+
else
6798+
PyErr_Clear();
6799+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
6800+
|| (buff->shape && buff->itemsize != 1)) {
67926801
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageFactory_getType" "', argument " "1"" of type '" "bytes-like object""'")
67936802
;
67946803
}
6795-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
67966804
arg1 = (Exiv2::byte *) buff->buf;
67976805
arg2 = (long) buff->len;
67986806
}
@@ -7029,13 +7037,17 @@ SWIGINTERN PyObject *_wrap_ImageFactory_createIo__SWIG_1(PyObject *self, Py_ssiz
70297037

70307038
if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
70317039
{
7032-
_global_view = PyMemoryView_GetContiguous(swig_obj[0], PyBUF_READ, 'A');
7033-
if (!_global_view) {
7034-
PyErr_Clear();
7040+
Py_buffer* buff = NULL;
7041+
_global_view = PyMemoryView_FromObject(swig_obj[0]);
7042+
if (_global_view)
7043+
buff = PyMemoryView_GET_BUFFER(_global_view);
7044+
else
7045+
PyErr_Clear();
7046+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
7047+
|| (buff->shape && buff->itemsize != 1)) {
70357048
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "ImageFactory_createIo" "', argument " "1"" of type '" "bytes-like object""'")
70367049
;
70377050
}
7038-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
70397051
arg1 = (Exiv2::byte *) buff->buf;
70407052
arg2 = (size_t) buff->len;
70417053
}

src/swig-0_27_7/types_wrap.cxx

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5822,13 +5822,17 @@ SWIGINTERN int _wrap_new_DataBuf__SWIG_2(PyObject *self, Py_ssize_t nobjs, PyObj
58225822

58235823
if ((nobjs < 1) || (nobjs > 1)) SWIG_fail;
58245824
{
5825-
_global_view = PyMemoryView_GetContiguous(swig_obj[0], PyBUF_READ, 'A');
5826-
if (!_global_view) {
5827-
PyErr_Clear();
5825+
Py_buffer* buff = NULL;
5826+
_global_view = PyMemoryView_FromObject(swig_obj[0]);
5827+
if (_global_view)
5828+
buff = PyMemoryView_GET_BUFFER(_global_view);
5829+
else
5830+
PyErr_Clear();
5831+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
5832+
|| (buff->shape && buff->itemsize != 1)) {
58285833
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "new_DataBuf" "', argument " "1"" of type '" "bytes-like object""'")
58295834
;
58305835
}
5831-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
58325836
arg1 = (Exiv2::byte *) buff->buf;
58335837
arg2 = (long) buff->len;
58345838
}
@@ -6157,13 +6161,17 @@ SWIGINTERN PyObject *_wrap_DataBuf___eq__(PyObject *self, PyObject *args) {
61576161
}
61586162
arg1 = reinterpret_cast< Exiv2::DataBuf * >(argp1);
61596163
{
6160-
_global_view = PyMemoryView_GetContiguous(swig_obj[0], PyBUF_READ, 'A');
6161-
if (!_global_view) {
6162-
PyErr_Clear();
6164+
Py_buffer* buff = NULL;
6165+
_global_view = PyMemoryView_FromObject(swig_obj[0]);
6166+
if (_global_view)
6167+
buff = PyMemoryView_GET_BUFFER(_global_view);
6168+
else
6169+
PyErr_Clear();
6170+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
6171+
|| (buff->shape && buff->itemsize != 1)) {
61636172
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DataBuf___eq__" "', argument " "2"" of type '" "bytes-like object""'")
61646173
;
61656174
}
6166-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
61676175
arg2 = (Exiv2::byte *) buff->buf;
61686176
arg3 = (long) buff->len;
61696177
}
@@ -6213,13 +6221,17 @@ SWIGINTERN PyObject *_wrap_DataBuf___ne__(PyObject *self, PyObject *args) {
62136221
}
62146222
arg1 = reinterpret_cast< Exiv2::DataBuf * >(argp1);
62156223
{
6216-
_global_view = PyMemoryView_GetContiguous(swig_obj[0], PyBUF_READ, 'A');
6217-
if (!_global_view) {
6218-
PyErr_Clear();
6224+
Py_buffer* buff = NULL;
6225+
_global_view = PyMemoryView_FromObject(swig_obj[0]);
6226+
if (_global_view)
6227+
buff = PyMemoryView_GET_BUFFER(_global_view);
6228+
else
6229+
PyErr_Clear();
6230+
if (!_global_view || !PyBuffer_IsContiguous(buff, 'A')
6231+
|| (buff->shape && buff->itemsize != 1)) {
62196232
SWIG_exception_fail(SWIG_ArgError(SWIG_TypeError), "in method '" "DataBuf___ne__" "', argument " "2"" of type '" "bytes-like object""'")
62206233
;
62216234
}
6222-
Py_buffer* buff = PyMemoryView_GET_BUFFER(_global_view);
62236235
arg2 = (Exiv2::byte *) buff->buf;
62246236
arg3 = (long) buff->len;
62256237
}

0 commit comments

Comments
 (0)