From 673b77c3ac81afb021f9f84f5a6e7db93f66e407 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= <lalinsky@gmail.com> Date: Sat, 10 Nov 2007 18:03:25 +0000 Subject: [PATCH] - Fixed crash in AttachedPictureFrame and GeneralEncapsulatedObjectFrame caused by using uninitialized pointer. (BUG:151078) - Make Frame::readStringField to actually read the string field. - Fixed parsing of APIC frames -- there is one-byte type between mime type and description. The code worked only thanks to the previous bug. git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@735035 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- .../id3v2/frames/attachedpictureframe.cpp | 7 ++- .../frames/generalencapsulatedobjectframe.cpp | 2 +- taglib/mpeg/id3v2/id3v2frame.cpp | 4 +- tests/test_id3v2.cpp | 59 +++++++++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp b/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp index 7033020f..be0e1d85 100644 --- a/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp +++ b/taglib/mpeg/id3v2/frames/attachedpictureframe.cpp @@ -54,8 +54,8 @@ AttachedPictureFrame::AttachedPictureFrame() : Frame("APIC") AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data) : Frame(data) { - setData(data); d = new AttachedPictureFramePrivate; + setData(data); } AttachedPictureFrame::~AttachedPictureFrame() @@ -132,9 +132,10 @@ void AttachedPictureFrame::parseFields(const ByteVector &data) d->textEncoding = String::Type(data[0]); - int pos = 1; + int pos = 1; - d->mimeType = readStringField(data, String::Latin1, &pos); + d->mimeType = readStringField(data, String::Latin1, &pos); + d->type = (TagLib::ID3v2::AttachedPictureFrame::Type)data[pos++]; d->description = readStringField(data, d->textEncoding, &pos); d->data = data.mid(pos); diff --git a/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp b/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp index 4ca02005..2d741cf8 100644 --- a/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp +++ b/taglib/mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp @@ -55,8 +55,8 @@ GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFrame() : Frame("GEOB") GeneralEncapsulatedObjectFrame::GeneralEncapsulatedObjectFrame(const ByteVector &data) : Frame(data) { - setData(data); d = new GeneralEncapsulatedObjectFramePrivate; + setData(data); } GeneralEncapsulatedObjectFrame::~GeneralEncapsulatedObjectFrame() diff --git a/taglib/mpeg/id3v2/id3v2frame.cpp b/taglib/mpeg/id3v2/id3v2frame.cpp index e79aa8e9..c743cafd 100644 --- a/taglib/mpeg/id3v2/id3v2frame.cpp +++ b/taglib/mpeg/id3v2/id3v2frame.cpp @@ -202,9 +202,11 @@ String Frame::readStringField(const ByteVector &data, String::Type encoding, int if(end < *position) return String::null; + String str = String(data.mid(*position, end - *position), encoding); + *position = end + delimiter.size(); - return String(data.mid(*position, end - *position), encoding); + return str; } diff --git a/tests/test_id3v2.cpp b/tests/test_id3v2.cpp index bb6db558..9a07765d 100644 --- a/tests/test_id3v2.cpp +++ b/tests/test_id3v2.cpp @@ -3,17 +3,35 @@ #include <stdio.h> #include <id3v2tag.h> #include <mpegfile.h> +#include <id3v2frame.h> #include <textidentificationframe.h> +#include <attachedpictureframe.h> +#include <generalencapsulatedobjectframe.h> using namespace std; using namespace TagLib; +class PublicFrame : public ID3v2::Frame +{ + public: + PublicFrame() : ID3v2::Frame(ByteVector("XXXX\0\0\0\0\0\0", 10)) {} + String readStringField(const ByteVector &data, String::Type encoding, + int *positon = 0) + { return ID3v2::Frame::readStringField(data, encoding, positon); } + virtual String toString() const { return String::null; } + virtual void parseFields(const ByteVector &) {} + virtual ByteVector renderFields() const { return ByteVector::null; } +}; + class TestID3v2 : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestID3v2); CPPUNIT_TEST(testUnsynchDecode); CPPUNIT_TEST(testUTF16BEDelimiter); CPPUNIT_TEST(testUTF16Delimiter); + CPPUNIT_TEST(testReadStringField); + CPPUNIT_TEST(testParseAPIC); + CPPUNIT_TEST(testParseGEOB); CPPUNIT_TEST(testBrokenFrame1); //CPPUNIT_TEST(testItunes24FrameSize); CPPUNIT_TEST_SUITE_END(); @@ -54,6 +72,47 @@ public: CPPUNIT_ASSERT(!f.ID3v2Tag()->frameListMap().contains("TENC")); } + void testReadStringField() + { + PublicFrame f; + ByteVector data("abc\0", 4); + String str = f.readStringField(data, String::Latin1); + CPPUNIT_ASSERT_EQUAL(String("abc"), str); + } + + // http://bugs.kde.org/show_bug.cgi?id=151078 + void testParseAPIC() + { + ID3v2::AttachedPictureFrame f(ByteVector("APIC" + "\x00\x00\x00\x07" + "\x00\x00" + "\x00" + "m\x00" + "\x01" + "d\x00" + "\x00", 17)); + CPPUNIT_ASSERT_EQUAL(String("m"), f.mimeType()); + CPPUNIT_ASSERT_EQUAL(ID3v2::AttachedPictureFrame::FileIcon, f.type()); + CPPUNIT_ASSERT_EQUAL(String("d"), f.description()); + } + + // http://bugs.kde.org/show_bug.cgi?id=151078 + void testParseGEOB() + { + ID3v2::GeneralEncapsulatedObjectFrame f(ByteVector("GEOB" + "\x00\x00\x00\x08" + "\x00\x00" + "\x00" + "m\x00" + "f\x00" + "d\x00" + "\x00", 18)); + CPPUNIT_ASSERT_EQUAL(String("m"), f.mimeType()); + CPPUNIT_ASSERT_EQUAL(String("f"), f.fileName()); + CPPUNIT_ASSERT_EQUAL(String("d"), f.description()); + } + + /*void testItunes24FrameSize() { MPEG::File f("data/005411.id3", false); -- 2.40.0