Fix for https://github.com/Exiv2/exiv2/issues/560 (eraseFamily() crashes in MSVC/Debug).

v0.27.3
clanmills 7 years ago committed by Luis Díaz Más
parent 062bad7535
commit c22a38cfb4

@ -219,10 +219,10 @@ namespace Exiv2 {
iterator erase(XmpData::iterator pos); iterator erase(XmpData::iterator pos);
/*! /*!
@brief Delete the Xmpdatum at iterator position pos and update pos @brief Delete the Xmpdatum at iterator position pos and update pos
eraseFamily erases data from the same family erases all following keys from the same family
See: https://github.com/Exiv2/exiv2/issues/521 See: https://github.com/Exiv2/exiv2/issues/521
*/ */
void eraseFamily(iterator &pos); void eraseFamily(XmpData::iterator& pos);
//! Delete all Xmpdatum instances resulting in an empty container. //! Delete all Xmpdatum instances resulting in an empty container.
void clear(); void clear();
//! Sort metadata by key //! Sort metadata by key

@ -1615,7 +1615,7 @@ namespace Action {
if (modifyCmd.metadataId_ == xmp) { if (modifyCmd.metadataId_ == xmp) {
Exiv2::XmpData::iterator pos; Exiv2::XmpData::iterator pos;
Exiv2::XmpKey xmpKey = Exiv2::XmpKey(modifyCmd.key_); Exiv2::XmpKey xmpKey = Exiv2::XmpKey(modifyCmd.key_);
while((pos = xmpData.findKey(xmpKey)) != xmpData.end()) { if((pos = xmpData.findKey(xmpKey)) != xmpData.end()) {
xmpData.eraseFamily(pos); xmpData.eraseFamily(pos);
} }
} }

@ -386,17 +386,29 @@ namespace Exiv2 {
return xmpMetadata_.erase(pos); return xmpMetadata_.erase(pos);
} }
void XmpData::eraseFamily(XmpData::iterator &pos) void XmpData::eraseFamily(XmpData::iterator& pos)
{ {
// https://github.com/Exiv2/exiv2/issues/521 // https://github.com/Exiv2/exiv2/issues/521
// delete 'children' of XMP composites (XmpSeq and XmpBag) // delete 'children' of XMP composites (XmpSeq and XmpBag)
std::string key = pos->key();
while ( pos != end() ) { // I build a StringVector of keys to remove
// Then I remove them with erase(....)
// erase() has nasty side effects on its argument
// The side effects are avoided by the two-step approach
// https://github.com/Exiv2/exiv2/issues/560
std::string key(pos->key());
Exiv2::StringVector keys;
while ( pos != xmpMetadata_.end() ) {
if ( pos->key().find(key)==0 ) { if ( pos->key().find(key)==0 ) {
erase(pos); keys.push_back(pos->key());
pos++;
} else { } else {
break ; break;
}
} }
// now erase the family!
for ( Exiv2::StringVector_i it = keys.begin() ; it != keys.end() ; it++ ) {
erase(findKey(Exiv2::XmpKey(*it)));
} }
} }

Loading…
Cancel
Save