diff --git a/taglib/mpeg/id3v2/id3v2synchdata.cpp b/taglib/mpeg/id3v2/id3v2synchdata.cpp index ddcd95b3..2aa99999 100644 --- a/taglib/mpeg/id3v2/id3v2synchdata.cpp +++ b/taglib/mpeg/id3v2/id3v2synchdata.cpp @@ -77,26 +77,22 @@ ByteVector SynchData::decode(const ByteVector &data) // We have this optimized method instead of using ByteVector::replace(), // since it makes a great difference when decoding huge unsynchronized frames. - if(data.size() < 2) - return data; + ByteVector result(data.size()); - ByteVector result = data; + ByteVector::ConstIterator src = data.begin(); + ByteVector::Iterator dst = result.begin(); - char *begin = result.data(); - char *end = begin + result.size(); - - char *dst = begin; - const char *src = begin; - - do { + while(src < data.end() - 1) { *dst++ = *src++; if(*(src - 1) == '\xff' && *src == '\x00') src++; + } - } while(src < end); + if(src < data.end()) + *dst++ = *src++; - result.resize(static_cast(dst - begin)); + result.resize(static_cast(dst - result.begin())); return result; } diff --git a/tests/test_synchdata.cpp b/tests/test_synchdata.cpp index bbd74d8b..b4ec4096 100644 --- a/tests/test_synchdata.cpp +++ b/tests/test_synchdata.cpp @@ -41,6 +41,7 @@ class TestID3v2SynchData : public CppUnit::TestFixture CPPUNIT_TEST(testDecode1); CPPUNIT_TEST(testDecode2); CPPUNIT_TEST(testDecode3); + CPPUNIT_TEST(testDecode4); CPPUNIT_TEST_SUITE_END(); public: @@ -113,6 +114,14 @@ public: CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\xff", 2), a); } + void testDecode4() + { + ByteVector a("\xff\xff\xff", 3); + a = ID3v2::SynchData::decode(a); + CPPUNIT_ASSERT_EQUAL((unsigned int)3, a.size()); + CPPUNIT_ASSERT_EQUAL(ByteVector("\xff\xff\xff", 3), a); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2SynchData);