Skip to content

Commit 8301adc

Browse files
Add Value index bounds check for exiv2 < 0.28
Before exiv2 0.27.5 Value (and subtypes) used [] for array access instead of .at(). This causes assertion errors if the index is out of range, so this commit adds bounds checks for any 0.27.x exiv2 version.
1 parent 3341382 commit 8301adc

10 files changed

Lines changed: 566 additions & 2 deletions

File tree

src/interface/shared/metadatum_wrappers.i

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ POINTER_STORE(container_type, datum_type)
4848
%ignore datum_type##_pointer::~datum_type##_pointer;
4949
%ignore datum_type##_pointer::operator*;
5050
%ignore datum_type##_pointer::size;
51+
%ignore datum_type##_pointer::count;
5152
%ignore datum_type##_pointer::_invalidate;
5253
%feature("docstring") datum_type##_pointer "
5354
Base class for pointers to :class:`"#datum_type"` objects.
@@ -92,6 +93,17 @@ public:
9293
return 0;
9394
return ptr->size();
9495
}
96+
#if EXIV2_VERSION_HEX < 0x001c0000
97+
// Provide count() C++ method for index bounds check
98+
long count() {
99+
if (invalidated)
100+
return 0;
101+
Exiv2::datum_type* ptr = **this;
102+
if (!ptr)
103+
return 0;
104+
return ptr->count();
105+
}
106+
#endif
95107
// Invalidate iterator unilaterally
96108
void _invalidate() { invalidated = true; }
97109
// Invalidate iterator if what it points to has been deleted

src/interface/value.i

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ KEEP_REFERENCE(const Exiv2::Value&)
7878
}
7979

8080
// for indexing multi-value values, assumes arg1 points to self
81-
%typemap(check) size_t idx %{
82-
if ($1 < 0 || $1 >= static_cast< size_t >(arg1->count())) {
81+
%typemap(check) (size_t idx), (long n) %{
82+
if ($1 < 0 || $1 >= static_cast< $1_ltype >(arg1->count())) {
8383
PyErr_Format(PyExc_IndexError, "index %d out of range", $1);
8484
SWIG_fail;
8585
}

src/swig-0_27_7/exif_wrap.cxx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4411,6 +4411,17 @@ class Exifdatum_pointer {
44114411
return 0;
44124412
return ptr->size();
44134413
}
4414+
#if 0x001b0700 < 0x001c0000
4415+
// Provide count() C++ method for index bounds check
4416+
long count() {
4417+
if (invalidated)
4418+
return 0;
4419+
Exiv2::Exifdatum* ptr = **this;
4420+
if (!ptr)
4421+
return 0;
4422+
return ptr->count();
4423+
}
4424+
#endif
44144425
// Invalidate iterator unilaterally
44154426
void _invalidate() { invalidated = true; }
44164427
// Invalidate iterator if what it points to has been deleted
@@ -6537,6 +6548,12 @@ SWIGINTERN PyObject *_wrap_Exifdatum_pointer_toLong(PyObject *self, PyObject *ar
65376548
}
65386549
arg2 = static_cast< long >(val2);
65396550
}
6551+
6552+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6553+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6554+
SWIG_fail;
6555+
}
6556+
65406557
{
65416558
try {
65426559
result = (long)(*arg1)->toLong(arg2);
@@ -6580,6 +6597,12 @@ SWIGINTERN PyObject *_wrap_Exifdatum_pointer_toFloat(PyObject *self, PyObject *a
65806597
}
65816598
arg2 = static_cast< long >(val2);
65826599
}
6600+
6601+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6602+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6603+
SWIG_fail;
6604+
}
6605+
65836606
{
65846607
try {
65856608
result = (float)(*arg1)->toFloat(arg2);
@@ -6623,6 +6646,12 @@ SWIGINTERN PyObject *_wrap_Exifdatum_pointer_toRational(PyObject *self, PyObject
66236646
}
66246647
arg2 = static_cast< long >(val2);
66256648
}
6649+
6650+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6651+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6652+
SWIG_fail;
6653+
}
6654+
66266655
{
66276656
try {
66286657
result = (*arg1)->toRational(arg2);
@@ -8138,6 +8167,12 @@ SWIGINTERN PyObject *_wrap_Exifdatum_toLong(PyObject *self, PyObject *args) {
81388167
}
81398168
arg2 = static_cast< long >(val2);
81408169
}
8170+
8171+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
8172+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
8173+
SWIG_fail;
8174+
}
8175+
81418176
{
81428177
try {
81438178
result = (long)((Exiv2::Exifdatum const *)arg1)->toLong(arg2);
@@ -8181,6 +8216,12 @@ SWIGINTERN PyObject *_wrap_Exifdatum_toFloat(PyObject *self, PyObject *args) {
81818216
}
81828217
arg2 = static_cast< long >(val2);
81838218
}
8219+
8220+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
8221+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
8222+
SWIG_fail;
8223+
}
8224+
81848225
{
81858226
try {
81868227
result = (float)((Exiv2::Exifdatum const *)arg1)->toFloat(arg2);
@@ -8224,6 +8265,12 @@ SWIGINTERN PyObject *_wrap_Exifdatum_toRational(PyObject *self, PyObject *args)
82248265
}
82258266
arg2 = static_cast< long >(val2);
82268267
}
8268+
8269+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
8270+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
8271+
SWIG_fail;
8272+
}
8273+
82278274
{
82288275
try {
82298276
result = ((Exiv2::Exifdatum const *)arg1)->toRational(arg2);

src/swig-0_27_7/iptc_wrap.cxx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4404,6 +4404,17 @@ class Iptcdatum_pointer {
44044404
return 0;
44054405
return ptr->size();
44064406
}
4407+
#if 0x001b0700 < 0x001c0000
4408+
// Provide count() C++ method for index bounds check
4409+
long count() {
4410+
if (invalidated)
4411+
return 0;
4412+
Exiv2::Iptcdatum* ptr = **this;
4413+
if (!ptr)
4414+
return 0;
4415+
return ptr->count();
4416+
}
4417+
#endif
44074418
// Invalidate iterator unilaterally
44084419
void _invalidate() { invalidated = true; }
44094420
// Invalidate iterator if what it points to has been deleted
@@ -6423,6 +6434,12 @@ SWIGINTERN PyObject *_wrap_Iptcdatum_pointer_toLong(PyObject *self, PyObject *ar
64236434
}
64246435
arg2 = static_cast< long >(val2);
64256436
}
6437+
6438+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6439+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6440+
SWIG_fail;
6441+
}
6442+
64266443
{
64276444
try {
64286445
result = (long)(*arg1)->toLong(arg2);
@@ -6466,6 +6483,12 @@ SWIGINTERN PyObject *_wrap_Iptcdatum_pointer_toFloat(PyObject *self, PyObject *a
64666483
}
64676484
arg2 = static_cast< long >(val2);
64686485
}
6486+
6487+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6488+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6489+
SWIG_fail;
6490+
}
6491+
64696492
{
64706493
try {
64716494
result = (float)(*arg1)->toFloat(arg2);
@@ -6509,6 +6532,12 @@ SWIGINTERN PyObject *_wrap_Iptcdatum_pointer_toRational(PyObject *self, PyObject
65096532
}
65106533
arg2 = static_cast< long >(val2);
65116534
}
6535+
6536+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6537+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6538+
SWIG_fail;
6539+
}
6540+
65126541
{
65136542
try {
65146543
result = (*arg1)->toRational(arg2);
@@ -7909,6 +7938,12 @@ SWIGINTERN PyObject *_wrap_Iptcdatum_toLong(PyObject *self, PyObject *args) {
79097938
}
79107939
arg2 = static_cast< long >(val2);
79117940
}
7941+
7942+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
7943+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
7944+
SWIG_fail;
7945+
}
7946+
79127947
{
79137948
try {
79147949
result = (long)((Exiv2::Iptcdatum const *)arg1)->toLong(arg2);
@@ -7952,6 +7987,12 @@ SWIGINTERN PyObject *_wrap_Iptcdatum_toFloat(PyObject *self, PyObject *args) {
79527987
}
79537988
arg2 = static_cast< long >(val2);
79547989
}
7990+
7991+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
7992+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
7993+
SWIG_fail;
7994+
}
7995+
79557996
{
79567997
try {
79577998
result = (float)((Exiv2::Iptcdatum const *)arg1)->toFloat(arg2);
@@ -7995,6 +8036,12 @@ SWIGINTERN PyObject *_wrap_Iptcdatum_toRational(PyObject *self, PyObject *args)
79958036
}
79968037
arg2 = static_cast< long >(val2);
79978038
}
8039+
8040+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
8041+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
8042+
SWIG_fail;
8043+
}
8044+
79988045
{
79998046
try {
80008047
result = ((Exiv2::Iptcdatum const *)arg1)->toRational(arg2);

src/swig-0_27_7/metadatum_wrap.cxx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6187,6 +6187,12 @@ SWIGINTERN PyObject *_wrap_Metadatum_toLong(PyObject *self, PyObject *args) {
61876187
}
61886188
arg2 = static_cast< long >(val2);
61896189
}
6190+
6191+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6192+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6193+
SWIG_fail;
6194+
}
6195+
61906196
{
61916197
try {
61926198
result = (long)((Exiv2::Metadatum const *)arg1)->toLong(arg2);
@@ -6230,6 +6236,12 @@ SWIGINTERN PyObject *_wrap_Metadatum_toFloat(PyObject *self, PyObject *args) {
62306236
}
62316237
arg2 = static_cast< long >(val2);
62326238
}
6239+
6240+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6241+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6242+
SWIG_fail;
6243+
}
6244+
62336245
{
62346246
try {
62356247
result = (float)((Exiv2::Metadatum const *)arg1)->toFloat(arg2);
@@ -6273,6 +6285,12 @@ SWIGINTERN PyObject *_wrap_Metadatum_toRational(PyObject *self, PyObject *args)
62736285
}
62746286
arg2 = static_cast< long >(val2);
62756287
}
6288+
6289+
if (arg2 < 0 || arg2 >= static_cast< long >(arg1->count())) {
6290+
PyErr_Format(PyExc_IndexError, "index %d out of range", arg2);
6291+
SWIG_fail;
6292+
}
6293+
62766294
{
62776295
try {
62786296
result = ((Exiv2::Metadatum const *)arg1)->toRational(arg2);

0 commit comments

Comments
 (0)