Skip to content

Commit 78acb9f

Browse files
Add validity checks to interator input typemaps
1 parent 42c0863 commit 78acb9f

9 files changed

Lines changed: 118 additions & 42 deletions

File tree

src/interface/shared/metadatum_wrappers.i

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public:
109109
%noexception container_type##_iterator::__iter__;
110110
%ignore container_type##_iterator::##container_type##_iterator;
111111
%ignore container_type##_iterator::operator*;
112+
%ignore container_type##_iterator::_invalidated;
112113
%ignore container_type##_iterator::_ptr;
113114
%feature("docstring") container_type##_iterator "
114115
Python wrapper for an :class:`" #container_type "` iterator. It has most of
@@ -153,12 +154,9 @@ public:
153154
return NULL;
154155
return &(*ptr);
155156
}
156-
// Access to ptr, for use in other methods
157-
Exiv2::container_type::iterator _ptr() const {
158-
if (invalidated)
159-
throw std::runtime_error("datum_type reference is invalid");
160-
return ptr;
161-
}
157+
// Direct access to ptr and invalidated, for use in input typemaps
158+
bool _invalidated() const { return invalidated; }
159+
Exiv2::container_type::iterator _ptr() const { return ptr; }
162160
};
163161
%}
164162

@@ -193,6 +191,10 @@ public:
193191
$typemap(in, container_type##_iterator*)
194192
argp = arg$argnum;
195193
}
194+
if (argp->_invalidated()) {
195+
SWIG_exception_fail(SWIG_ValueError,
196+
"in method '$symname', argument $argnum points to deleted data");
197+
}
196198
$1 = argp->_ptr();
197199
%}
198200
%typemap(in) Exiv2::container_type::iterator&
@@ -203,6 +205,10 @@ public:
203205
$typemap(in, container_type##_iterator*)
204206
argp = arg$argnum;
205207
}
208+
if (argp->_invalidated()) {
209+
SWIG_exception_fail(SWIG_ValueError,
210+
"in method '$symname', argument $argnum points to deleted data");
211+
}
206212
it = argp->_ptr();
207213
$1 = ⁢
208214
}

src/swig-0_27_7/exif_wrap.cxx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5380,12 +5380,9 @@ class ExifData_iterator: public Exifdatum_pointer {
53805380
return NULL;
53815381
return &(*ptr);
53825382
}
5383-
// Access to ptr, for use in other methods
5384-
Exiv2::ExifData::iterator _ptr() const {
5385-
if (invalidated)
5386-
throw std::runtime_error("Exifdatum reference is invalid");
5387-
return ptr;
5388-
}
5383+
// Direct access to ptr and invalidated, for use in input typemaps
5384+
bool _invalidated() const { return invalidated; }
5385+
Exiv2::ExifData::iterator _ptr() const { return ptr; }
53895386
};
53905387

53915388

@@ -9707,6 +9704,10 @@ SWIGINTERN PyObject *_wrap_ExifData_erase__SWIG_0(PyObject *self, PyObject *args
97079704
arg2 = reinterpret_cast< ExifData_iterator * >(argp10);
97089705
argp2 = arg2;
97099706
}
9707+
if (argp2->_invalidated()) {
9708+
SWIG_exception_fail(SWIG_ValueError,
9709+
"in method 'ExifData_erase', argument 2 points to deleted data");
9710+
}
97109711
arg2 = argp2->_ptr();
97119712

97129713
{
@@ -9777,6 +9778,10 @@ SWIGINTERN PyObject *_wrap_ExifData_erase__SWIG_1(PyObject *self, PyObject *args
97779778
arg2 = reinterpret_cast< ExifData_iterator * >(argp10);
97789779
argp2 = arg2;
97799780
}
9781+
if (argp2->_invalidated()) {
9782+
SWIG_exception_fail(SWIG_ValueError,
9783+
"in method 'ExifData_erase', argument 2 points to deleted data");
9784+
}
97809785
arg2 = argp2->_ptr();
97819786

97829787

@@ -9789,6 +9794,10 @@ SWIGINTERN PyObject *_wrap_ExifData_erase__SWIG_1(PyObject *self, PyObject *args
97899794
arg3 = reinterpret_cast< ExifData_iterator * >(argp11);
97909795
argp3 = arg3;
97919796
}
9797+
if (argp3->_invalidated()) {
9798+
SWIG_exception_fail(SWIG_ValueError,
9799+
"in method 'ExifData_erase', argument 3 points to deleted data");
9800+
}
97929801
arg3 = argp3->_ptr();
97939802

97949803
{

src/swig-0_27_7/iptc_wrap.cxx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5373,12 +5373,9 @@ class IptcData_iterator: public Iptcdatum_pointer {
53735373
return NULL;
53745374
return &(*ptr);
53755375
}
5376-
// Access to ptr, for use in other methods
5377-
Exiv2::IptcData::iterator _ptr() const {
5378-
if (invalidated)
5379-
throw std::runtime_error("Iptcdatum reference is invalid");
5380-
return ptr;
5381-
}
5376+
// Direct access to ptr and invalidated, for use in input typemaps
5377+
bool _invalidated() const { return invalidated; }
5378+
Exiv2::IptcData::iterator _ptr() const { return ptr; }
53825379
};
53835380

53845381

@@ -8766,6 +8763,10 @@ SWIGINTERN PyObject *_wrap_IptcData_erase(PyObject *self, PyObject *args) {
87668763
arg2 = reinterpret_cast< IptcData_iterator * >(argp10);
87678764
argp2 = arg2;
87688765
}
8766+
if (argp2->_invalidated()) {
8767+
SWIG_exception_fail(SWIG_ValueError,
8768+
"in method 'IptcData_erase', argument 2 points to deleted data");
8769+
}
87698770
arg2 = argp2->_ptr();
87708771

87718772
{

src/swig-0_27_7/xmp_wrap.cxx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5375,12 +5375,9 @@ class XmpData_iterator: public Xmpdatum_pointer {
53755375
return NULL;
53765376
return &(*ptr);
53775377
}
5378-
// Access to ptr, for use in other methods
5379-
Exiv2::XmpData::iterator _ptr() const {
5380-
if (invalidated)
5381-
throw std::runtime_error("Xmpdatum reference is invalid");
5382-
return ptr;
5383-
}
5378+
// Direct access to ptr and invalidated, for use in input typemaps
5379+
bool _invalidated() const { return invalidated; }
5380+
Exiv2::XmpData::iterator _ptr() const { return ptr; }
53845381
};
53855382

53865383

@@ -8620,6 +8617,10 @@ SWIGINTERN PyObject *_wrap_XmpData_erase(PyObject *self, PyObject *args) {
86208617
arg2 = reinterpret_cast< XmpData_iterator * >(argp10);
86218618
argp2 = arg2;
86228619
}
8620+
if (argp2->_invalidated()) {
8621+
SWIG_exception_fail(SWIG_ValueError,
8622+
"in method 'XmpData_erase', argument 2 points to deleted data");
8623+
}
86238624
arg2 = argp2->_ptr();
86248625

86258626
{
@@ -8685,6 +8686,10 @@ SWIGINTERN PyObject *_wrap_XmpData_eraseFamily(PyObject *self, PyObject *args) {
86858686
arg2 = reinterpret_cast< XmpData_iterator * >(argp10);
86868687
argp2 = arg2;
86878688
}
8689+
if (argp2->_invalidated()) {
8690+
SWIG_exception_fail(SWIG_ValueError,
8691+
"in method 'XmpData_eraseFamily', argument 2 points to deleted data");
8692+
}
86888693
it2 = argp2->_ptr();
86898694
arg2 = &it2;
86908695
}

src/swig-0_28_5/exif_wrap.cxx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5542,12 +5542,9 @@ class ExifData_iterator: public Exifdatum_pointer {
55425542
return NULL;
55435543
return &(*ptr);
55445544
}
5545-
// Access to ptr, for use in other methods
5546-
Exiv2::ExifData::iterator _ptr() const {
5547-
if (invalidated)
5548-
throw std::runtime_error("Exifdatum reference is invalid");
5549-
return ptr;
5550-
}
5545+
// Direct access to ptr and invalidated, for use in input typemaps
5546+
bool _invalidated() const { return invalidated; }
5547+
Exiv2::ExifData::iterator _ptr() const { return ptr; }
55515548
};
55525549

55535550

@@ -9911,6 +9908,10 @@ SWIGINTERN PyObject *_wrap_ExifData_erase__SWIG_0(PyObject *self, PyObject *args
99119908
arg2 = reinterpret_cast< ExifData_iterator * >(argp10);
99129909
argp2 = arg2;
99139910
}
9911+
if (argp2->_invalidated()) {
9912+
SWIG_exception_fail(SWIG_ValueError,
9913+
"in method 'ExifData_erase', argument 2 points to deleted data");
9914+
}
99149915
arg2 = argp2->_ptr();
99159916

99169917
{
@@ -9981,6 +9982,10 @@ SWIGINTERN PyObject *_wrap_ExifData_erase__SWIG_1(PyObject *self, PyObject *args
99819982
arg2 = reinterpret_cast< ExifData_iterator * >(argp10);
99829983
argp2 = arg2;
99839984
}
9985+
if (argp2->_invalidated()) {
9986+
SWIG_exception_fail(SWIG_ValueError,
9987+
"in method 'ExifData_erase', argument 2 points to deleted data");
9988+
}
99849989
arg2 = argp2->_ptr();
99859990

99869991

@@ -9993,6 +9998,10 @@ SWIGINTERN PyObject *_wrap_ExifData_erase__SWIG_1(PyObject *self, PyObject *args
99939998
arg3 = reinterpret_cast< ExifData_iterator * >(argp11);
99949999
argp3 = arg3;
999510000
}
10001+
if (argp3->_invalidated()) {
10002+
SWIG_exception_fail(SWIG_ValueError,
10003+
"in method 'ExifData_erase', argument 3 points to deleted data");
10004+
}
999610005
arg3 = argp3->_ptr();
999710006

999810007
{

src/swig-0_28_5/iptc_wrap.cxx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5535,12 +5535,9 @@ class IptcData_iterator: public Iptcdatum_pointer {
55355535
return NULL;
55365536
return &(*ptr);
55375537
}
5538-
// Access to ptr, for use in other methods
5539-
Exiv2::IptcData::iterator _ptr() const {
5540-
if (invalidated)
5541-
throw std::runtime_error("Iptcdatum reference is invalid");
5542-
return ptr;
5543-
}
5538+
// Direct access to ptr and invalidated, for use in input typemaps
5539+
bool _invalidated() const { return invalidated; }
5540+
Exiv2::IptcData::iterator _ptr() const { return ptr; }
55445541
};
55455542

55465543

@@ -8977,6 +8974,10 @@ SWIGINTERN PyObject *_wrap_IptcData_erase(PyObject *self, PyObject *args) {
89778974
arg2 = reinterpret_cast< IptcData_iterator * >(argp10);
89788975
argp2 = arg2;
89798976
}
8977+
if (argp2->_invalidated()) {
8978+
SWIG_exception_fail(SWIG_ValueError,
8979+
"in method 'IptcData_erase', argument 2 points to deleted data");
8980+
}
89808981
arg2 = argp2->_ptr();
89818982

89828983
{

src/swig-0_28_5/xmp_wrap.cxx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5537,12 +5537,9 @@ class XmpData_iterator: public Xmpdatum_pointer {
55375537
return NULL;
55385538
return &(*ptr);
55395539
}
5540-
// Access to ptr, for use in other methods
5541-
Exiv2::XmpData::iterator _ptr() const {
5542-
if (invalidated)
5543-
throw std::runtime_error("Xmpdatum reference is invalid");
5544-
return ptr;
5545-
}
5540+
// Direct access to ptr and invalidated, for use in input typemaps
5541+
bool _invalidated() const { return invalidated; }
5542+
Exiv2::XmpData::iterator _ptr() const { return ptr; }
55465543
};
55475544

55485545

@@ -8883,6 +8880,10 @@ SWIGINTERN PyObject *_wrap_XmpData_erase(PyObject *self, PyObject *args) {
88838880
arg2 = reinterpret_cast< XmpData_iterator * >(argp10);
88848881
argp2 = arg2;
88858882
}
8883+
if (argp2->_invalidated()) {
8884+
SWIG_exception_fail(SWIG_ValueError,
8885+
"in method 'XmpData_erase', argument 2 points to deleted data");
8886+
}
88868887
arg2 = argp2->_ptr();
88878888

88888889
{
@@ -8948,6 +8949,10 @@ SWIGINTERN PyObject *_wrap_XmpData_eraseFamily(PyObject *self, PyObject *args) {
89488949
arg2 = reinterpret_cast< XmpData_iterator * >(argp10);
89498950
argp2 = arg2;
89508951
}
8952+
if (argp2->_invalidated()) {
8953+
SWIG_exception_fail(SWIG_ValueError,
8954+
"in method 'XmpData_eraseFamily', argument 2 points to deleted data");
8955+
}
89518956
it2 = argp2->_ptr();
89528957
arg2 = &it2;
89538958
}

tests/test_exif.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ def test_pointers(self):
291291
data2.add(datum)
292292
data2.add(datum_iter)
293293
data2.add(datum_pointer)
294+
datum_iter2 = data2.begin()
295+
data2.erase(datum_iter2)
296+
with self.assertRaises(ValueError):
297+
data2.erase(datum_iter2)
294298
# __eq__ operator
295299
self.assertEqual(datum, datum_iter)
296300
self.assertEqual(datum, datum_pointer)

tests/test_xmp.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,42 @@ def test_XmpDatum(self):
202202
del datum2
203203
self._test_datum(datum)
204204

205+
def test_pointers(self):
206+
data = exiv2.XmpData()
207+
data.add(exiv2.Xmpdatum(
208+
exiv2.XmpKey('Xmp.xmp.CreatorTool'), exiv2.AsciiValue('Acme')))
209+
# output typemaps
210+
datum_iter = data.begin()
211+
self.assertIsInstance(datum_iter, exiv2.XmpData_iterator)
212+
datum_pointer = data[datum_iter.key()]
213+
self.assertIsInstance(datum_pointer, exiv2.Xmpdatum_pointer)
214+
# __deref__ operator
215+
datum = datum_iter.__deref__()
216+
self.assertIsInstance(datum, exiv2.Xmpdatum)
217+
datum = datum_pointer.__deref__()
218+
self.assertIsInstance(datum, exiv2.Xmpdatum)
219+
# input typemaps
220+
datum2 = exiv2.Xmpdatum(datum)
221+
datum2 = exiv2.Xmpdatum(datum_iter)
222+
datum2 = exiv2.Xmpdatum(datum_pointer)
223+
data2 = exiv2.XmpData()
224+
data2.add(datum)
225+
data2.add(datum_iter)
226+
data2.add(datum_pointer)
227+
datum_iter2 = data2.begin()
228+
data2.erase(datum_iter2)
229+
with self.assertRaises(ValueError):
230+
data2.erase(datum_iter2)
231+
with self.assertRaises(ValueError):
232+
data2.eraseFamily(datum_iter2)
233+
# __eq__ operator
234+
self.assertEqual(datum, datum_iter)
235+
self.assertEqual(datum, datum_pointer)
236+
self.assertEqual(datum_iter, datum)
237+
self.assertEqual(datum_iter, datum_pointer)
238+
self.assertEqual(datum_pointer, datum)
239+
self.assertEqual(datum_pointer, datum_iter)
240+
205241
def test_ref_counts(self):
206242
self.image.readMetadata()
207243
# xmpData keeps a reference to image

0 commit comments

Comments
 (0)