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