From: Lukáš Lalinský Date: Sat, 1 Dec 2007 09:15:23 +0000 (+0000) Subject: Add a hack to read ID2v2.4 frames with v2.3-like sizes, written by iTunes. X-Git-Tag: v1.5~67 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c4a21adb8e0baa1ef8c8c7e448f5027384a559cc;p=taglib Add a hack to read ID2v2.4 frames with v2.3-like sizes, written by iTunes. The code is inside a '#ifndef NO_ITUNES_HACKS' block, so I hope it's ok to add it. git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@743534 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- diff --git a/taglib/mpeg/id3v2/id3v2frame.cpp b/taglib/mpeg/id3v2/id3v2frame.cpp index c743cafd..49e57b96 100644 --- a/taglib/mpeg/id3v2/id3v2frame.cpp +++ b/taglib/mpeg/id3v2/id3v2frame.cpp @@ -54,6 +54,19 @@ public: Frame::Header *header; }; +bool isValidFrameID(const ByteVector &frameID) +{ + if(frameID.size() != 4) { + return false; + } + for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) { + if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) { + return false; + } + } + return true; +} + //////////////////////////////////////////////////////////////////////////////// // static methods //////////////////////////////////////////////////////////////////////////////// @@ -394,6 +407,17 @@ void Frame::Header::setData(const ByteVector &data, uint version) // the frame header (structure 4) d->frameSize = SynchData::toUInt(data.mid(4, 4)); +#ifndef NO_ITUNES_HACKS + // iTunes writes v2.4 tags with v2.3-like frame sizes + if(d->frameSize > 127) { + if(!isValidFrameID(data.mid(d->frameSize + 10, 4))) { + unsigned int uintSize = data.mid(4, 4).toUInt(); + if(isValidFrameID(data.mid(uintSize + 10, 4))) { + d->frameSize = uintSize; + } + } + } +#endif { // read the first byte of flags std::bitset<8> flags(data[8]); diff --git a/tests/data/005411.id3 b/tests/data/005411.id3 new file mode 100644 index 00000000..ab2e0997 Binary files /dev/null and b/tests/data/005411.id3 differ diff --git a/tests/test_id3v2.cpp b/tests/test_id3v2.cpp index 0cd43546..d4566555 100644 --- a/tests/test_id3v2.cpp +++ b/tests/test_id3v2.cpp @@ -39,7 +39,7 @@ class TestID3v2 : public CppUnit::TestFixture CPPUNIT_TEST(testParseUniqueFileIdentifierFrame); CPPUNIT_TEST(testParseEmptyUniqueFileIdentifierFrame); CPPUNIT_TEST(testBrokenFrame1); - //CPPUNIT_TEST(testItunes24FrameSize); + CPPUNIT_TEST(testItunes24FrameSize); CPPUNIT_TEST(testParseUrlLinkFrame); CPPUNIT_TEST(testRenderUrlLinkFrame); CPPUNIT_TEST(testParseUserUrlLinkFrame); @@ -221,13 +221,13 @@ public: f.render()); } - /*void testItunes24FrameSize() + void testItunes24FrameSize() { MPEG::File f("data/005411.id3", false); CPPUNIT_ASSERT(f.tag()); CPPUNIT_ASSERT(f.ID3v2Tag()->frameListMap().contains("TIT2")); CPPUNIT_ASSERT_EQUAL(String("Sunshine Superman"), f.ID3v2Tag()->frameListMap()["TIT2"].front()->toString()); - }*/ + } };