Skip to content

Commit cb1d952

Browse files
Invalidate iterator if its data is deleted
This removes another potential segfault. Requires swig >= 4.4
1 parent e55d835 commit cb1d952

8 files changed

Lines changed: 37 additions & 0 deletions

File tree

src/interface/shared/containers.i

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
base_class::__setitem__;
3636
%feature("python:slot", "sq_contains", functype="objobjproc")
3737
base_class::__contains__;
38+
%typemap(in, numinputs=0) PyObject* py_self {$1 = self;}
3839
%extend base_class {
3940
%fragment("get_type_id"{datum_type});
4041
%fragment("set_value_from_py"{datum_type});
@@ -60,12 +61,19 @@
6061
datum_type* datum = &(*$self)[key];
6162
return set_value_from_py(datum, py_value);
6263
}
64+
#if SWIG_VERSION >= 0x040400
65+
PyObject* __setitem__(PyObject* py_self, const std::string& key) {
66+
#else
6367
PyObject* __setitem__(const std::string& key) {
68+
#endif
6469
base_class::iterator pos = $self->findKey(key_type(key));
6570
if (pos == $self->end()) {
6671
PyErr_SetString(PyExc_KeyError, key.c_str());
6772
return NULL;
6873
}
74+
#if SWIG_VERSION >= 0x040400
75+
invalidate_iterators(py_self, pos, pos);
76+
#endif
6977
$self->erase(pos);
7078
return SWIG_Py_Void();
7179
}

src/swig-0_27_7/exif_wrap.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5565,11 +5565,15 @@ SWIGINTERN PyObject *Exiv2_ExifData___setitem____SWIG_2(Exiv2::ExifData *self,st
55655565
return set_value_from_py(datum, py_value);
55665566
}
55675567
SWIGINTERN PyObject *Exiv2_ExifData___setitem____SWIG_3(Exiv2::ExifData *self,std::string const &key){
5568+
55685569
Exiv2::ExifData::iterator pos = self->findKey(Exiv2::ExifKey(key));
55695570
if (pos == self->end()) {
55705571
PyErr_SetString(PyExc_KeyError, key.c_str());
55715572
return NULL;
55725573
}
5574+
5575+
5576+
55735577
self->erase(pos);
55745578
return SWIG_Py_Void();
55755579
}

src/swig-0_27_7/iptc_wrap.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5505,11 +5505,15 @@ SWIGINTERN PyObject *Exiv2_IptcData___setitem____SWIG_2(Exiv2::IptcData *self,st
55055505
return set_value_from_py(datum, py_value);
55065506
}
55075507
SWIGINTERN PyObject *Exiv2_IptcData___setitem____SWIG_3(Exiv2::IptcData *self,std::string const &key){
5508+
55085509
Exiv2::IptcData::iterator pos = self->findKey(Exiv2::IptcKey(key));
55095510
if (pos == self->end()) {
55105511
PyErr_SetString(PyExc_KeyError, key.c_str());
55115512
return NULL;
55125513
}
5514+
5515+
5516+
55135517
self->erase(pos);
55145518
return SWIG_Py_Void();
55155519
}

src/swig-0_27_7/xmp_wrap.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5453,11 +5453,15 @@ SWIGINTERN PyObject *Exiv2_XmpData___setitem____SWIG_2(Exiv2::XmpData *self,std:
54535453
return set_value_from_py(datum, py_value);
54545454
}
54555455
SWIGINTERN PyObject *Exiv2_XmpData___setitem____SWIG_3(Exiv2::XmpData *self,std::string const &key){
5456+
54565457
Exiv2::XmpData::iterator pos = self->findKey(Exiv2::XmpKey(key));
54575458
if (pos == self->end()) {
54585459
PyErr_SetString(PyExc_KeyError, key.c_str());
54595460
return NULL;
54605461
}
5462+
5463+
5464+
54615465
self->erase(pos);
54625466
return SWIG_Py_Void();
54635467
}

src/swig-0_28_5/exif_wrap.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5668,11 +5668,15 @@ SWIGINTERN PyObject *Exiv2_ExifData___setitem____SWIG_2(Exiv2::ExifData *self,st
56685668
return set_value_from_py(datum, py_value);
56695669
}
56705670
SWIGINTERN PyObject *Exiv2_ExifData___setitem____SWIG_3(Exiv2::ExifData *self,std::string const &key){
5671+
56715672
Exiv2::ExifData::iterator pos = self->findKey(Exiv2::ExifKey(key));
56725673
if (pos == self->end()) {
56735674
PyErr_SetString(PyExc_KeyError, key.c_str());
56745675
return NULL;
56755676
}
5677+
5678+
5679+
56765680
self->erase(pos);
56775681
return SWIG_Py_Void();
56785682
}

src/swig-0_28_5/iptc_wrap.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5615,11 +5615,15 @@ SWIGINTERN PyObject *Exiv2_IptcData___setitem____SWIG_2(Exiv2::IptcData *self,st
56155615
return set_value_from_py(datum, py_value);
56165616
}
56175617
SWIGINTERN PyObject *Exiv2_IptcData___setitem____SWIG_3(Exiv2::IptcData *self,std::string const &key){
5618+
56185619
Exiv2::IptcData::iterator pos = self->findKey(Exiv2::IptcKey(key));
56195620
if (pos == self->end()) {
56205621
PyErr_SetString(PyExc_KeyError, key.c_str());
56215622
return NULL;
56225623
}
5624+
5625+
5626+
56235627
self->erase(pos);
56245628
return SWIG_Py_Void();
56255629
}

src/swig-0_28_5/xmp_wrap.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5615,11 +5615,15 @@ SWIGINTERN PyObject *Exiv2_XmpData___setitem____SWIG_2(Exiv2::XmpData *self,std:
56155615
return set_value_from_py(datum, py_value);
56165616
}
56175617
SWIGINTERN PyObject *Exiv2_XmpData___setitem____SWIG_3(Exiv2::XmpData *self,std::string const &key){
5618+
56185619
Exiv2::XmpData::iterator pos = self->findKey(Exiv2::XmpKey(key));
56195620
if (pos == self->end()) {
56205621
PyErr_SetString(PyExc_KeyError, key.c_str());
56215622
return NULL;
56225623
}
5624+
5625+
5626+
56235627
self->erase(pos);
56245628
return SWIG_Py_Void();
56255629
}

tests/test_exif.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,13 @@ def test_ExifData(self):
104104
# access by key
105105
self.assertEqual('Exif.Image.Artist' in data, True)
106106
self.assertIsInstance(data['Exif.Image.Artist'], exiv2.Exifdatum)
107+
k = data.findKey(exiv2.ExifKey('Exif.Image.Artist'))
107108
del data['Exif.Image.Artist']
108109
self.assertEqual('Exif.Image.Artist' in data, False)
110+
if 'iterators' in data._private_data_:
111+
# swig >= 4.4
112+
with self.assertRaises(RuntimeError):
113+
k.key()
109114
data['Exif.Image.Artist'] = 'Fred'
110115
self.assertEqual('Exif.Image.Artist' in data, True)
111116
self.assertIsInstance(data['Exif.Image.Artist'], exiv2.Exifdatum)

0 commit comments

Comments
 (0)