From cfbaf3459776e45cdbf2954de57bde8b689264fa Mon Sep 17 00:00:00 2001 From: Tsuda Kageyu Date: Thu, 1 Dec 2016 10:50:30 +0900 Subject: [PATCH] Prevent the segment table of Ogg pages from exceeding the size limit. --- taglib/ogg/oggpage.cpp | 8 ++++---- tests/test_ogg.cpp | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/taglib/ogg/oggpage.cpp b/taglib/ogg/oggpage.cpp index 75aea22a..414d3d53 100644 --- a/taglib/ogg/oggpage.cpp +++ b/taglib/ogg/oggpage.cpp @@ -208,15 +208,15 @@ List Ogg::Page::paginate(const ByteVectorList &packets, static const unsigned int SplitSize = 32 * 255; - // Force repagination if the packets are too large for a page. + // Force repagination if the segment table will exceed the size limit. if(strategy != Repaginate) { - size_t totalSize = packets.size(); + size_t tableSize = 0; for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it) - totalSize += it->size(); + tableSize += it->size() / 255 + 1; - if(totalSize > 255 * 255) + if(tableSize > 255) strategy = Repaginate; } diff --git a/tests/test_ogg.cpp b/tests/test_ogg.cpp index af2d5b94..5569e59c 100644 --- a/tests/test_ogg.cpp +++ b/tests/test_ogg.cpp @@ -42,7 +42,8 @@ class TestOGG : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestOGG); CPPUNIT_TEST(testSimple); - CPPUNIT_TEST(testSplitPackets); + CPPUNIT_TEST(testSplitPackets1); + CPPUNIT_TEST(testSplitPackets2); CPPUNIT_TEST(testDictInterface1); CPPUNIT_TEST(testDictInterface2); CPPUNIT_TEST(testAudioProperties); @@ -67,7 +68,7 @@ public: } } - void testSplitPackets() + void testSplitPackets1() { ScopedFileCopy copy("empty", ".ogg"); string newname = copy.fileName(); @@ -110,6 +111,33 @@ public: } } + void testSplitPackets2() + { + ScopedFileCopy copy("empty", ".ogg"); + string newname = copy.fileName(); + + const String text = longText(60890, true); + + { + Vorbis::File f(newname.c_str()); + f.tag()->setTitle(text); + f.save(); + } + { + Vorbis::File f(newname.c_str()); + CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT_EQUAL(text, f.tag()->title()); + + f.tag()->setTitle("ABCDE"); + f.save(); + } + { + Vorbis::File f(newname.c_str()); + CPPUNIT_ASSERT(f.isValid()); + CPPUNIT_ASSERT_EQUAL(String("ABCDE"), f.tag()->title()); + } + } + void testDictInterface1() { ScopedFileCopy copy("empty", ".ogg"); -- 2.40.0