Version: 1.3 (using KDE KDE 3.3.1) Installed from: Gentoo Packages Compiler: gcc 3.4.2-r2 OS: Linux tryed to scan my audio collection with amarok. it crashed on a mpc file. when i hold the mouse over that file in Konqueror it crashes also. it seems to be a bug in libtag 1.3 i will attach the mpc file which crashes libtag 1.3
http://ita-info.de/badmpc.mpc <- ok there you can find on of my problem files
just tried the latest cvs, same problem
Ok, I'm able to reproduce this here. Looking into it.
CVS commit by wheeler: Make sure that there's (a) data in a bytevector that we're trying to convert to an integer before trying to convert it and (b) make sure that there's data in an APE::Item before trying to parse it. BUG:92028 M +6 -1 ape/apeitem.cpp 1.5 M +6 -0 toolkit/tbytevector.cpp 1.46 --- kdesupport/taglib/ape/apeitem.cpp #1.4:1.5 @@ -124,6 +124,11 @@ bool APE::Item::isEmpty() const } -void APE::Item::parse(const ByteVector& data) +void APE::Item::parse(const ByteVector &data) { + if(data.size() < 10) { + debug("APE::Item::parse() -- no data in item"); + return; + } + uint valueLength = data.mid(0, 4).toUInt(false); uint flags = data.mid(4, 4).toUInt(false); --- kdesupport/taglib/toolkit/tbytevector.cpp #1.45:1.46 @@ -190,4 +190,10 @@ namespace TagLib { { T sum = 0; + + if(data.size() <= 0) { + debug("ByteVectorMirror::toNumber<T>() -- data is empty, returning 0"); + return sum; + } + uint size = sizeof(T); uint last = data.size() > size ? size - 1 : data.size() - 1;
ok thanks, now it works for most of my mpc files. BUT, now it crashes on a few mpc files which hat worked before the bugfix. I will upload such a new bad mpc file to http://ita-info.de/badmpc2.mpc Thanks in advance danielw
ok new opened
ok more infos, it doesn really crash but terminate itself, here the output of tagread (one of the examples programs of taglib) ******************** "/home/danielw/Musik/Rage Against the Maschine/1992 - RageAgainst the Maschine/04. Settle for Nothing.mpc" ******************** TagLib: APE::Item::parse() -- no data in item terminate called after throwing an instance of 'std::bad_alloc' what(): St9bad_alloc
Thanks for looking into these. After I took some time to familiarize myself with the format (this code was contributed by someone else) I saw that these files are broken (they indicate that they have more attributes than they actually do), but that the code wasn't very robust in checking for such things. I've got a fix now that works for both files. Thanks for trying this out with various files -- I usually don't catch the MPC bugs since I don't use them myself.
CVS commit by wheeler: Do bounds checking before assuming that just because we've been told that there are actually more items that there actually are. BUG:92028 M +2 -2 ape-tag-format.txt 1.2 M +3 -1 apeitem.cpp 1.7 M +10 -4 apetag.cpp 1.8 M +6 -0 apetag.h 1.6 --- kdesupport/taglib/ape/ape-tag-format.txt #1.1:1.2 @@ -88,5 +88,5 @@ | | | compatibility) | |----------------|---------|------------------------------------------------| -|Item Count | 4 bytes | Number of items in the tag | +| Item Count | 4 bytes | Number of items in the tag | |----------------|---------|------------------------------------------------| | Tag Flags | 4 bytes | Global flags | @@ -168,3 +168,3 @@ Sections 5 - 7 haven't yet been converted from: -http://www.personal.uni-jena.de/~pfk/mpp/sv8/apetag.html \ No newline at end of file +http://www.personal.uni-jena.de/~pfk/mpp/sv8/apetag.html --- kdesupport/taglib/ape/apeitem.cpp #1.6:1.7 @@ -127,5 +127,7 @@ bool APE::Item::isEmpty() const void APE::Item::parse(const ByteVector &data) { - if(data.size() < 10) { + // 11 bytes is the minimum size for an APE item + + if(data.size() < 11) { debug("APE::Item::parse() -- no data in item"); return; --- kdesupport/taglib/ape/apetag.cpp #1.7:1.8 @@ -214,5 +214,5 @@ void APE::Tag::read() d->file->seek(d->tagOffset + Footer::size() - d->footer.tagSize()); - parse(d->file->readBlock(d->footer.tagSize() - Footer::size()), d->footer.itemCount()); + parse(d->file->readBlock(d->footer.tagSize() - Footer::size())); } } @@ -239,9 +239,16 @@ ByteVector APE::Tag::render() const } -void APE::Tag::parse(const ByteVector &data, uint count) +void APE::Tag::parse(const ByteVector &data, uint) +{ + parse(data); +} + +void APE::Tag::parse(const ByteVector &data) { uint pos = 0; - while(count > 0) { + // 11 bytes is the minimum size for an APE item + + for(uint i = 0; i < d->footer.itemCount() && pos <= data.size() - 11; i++) { APE::Item item; item.parse(data.mid(pos)); @@ -250,5 +257,4 @@ void APE::Tag::parse(const ByteVector &d pos += item.size(); - count--; } } --- kdesupport/taglib/ape/apetag.h #1.5:1.6 @@ -143,7 +143,13 @@ namespace TagLib { /*! * Parses the body of the tag in \a data with \a count items. + * \deprecated Please use the version that doesn't require an item count. */ void parse(const ByteVector &data, uint count); + /*! + * Parses the body of the tag in \a data. + */ + void parse(const ByteVector &data); + private: Tag(const Tag &);