mirror of
https://github.com/taglib/taglib.git
synced 2025-07-18 13:04:18 -04:00
Fix writing of new RIFF chunks at even positions
If the last chunk had an odd size, the new chunk would have been written at odd position, which is incorrect. This is based on the patch by Jens Dyffort, but I ended up changing the implementation to correctly handle subsequential updates to the file. The whole RIFF code really needs to be rewritten in a different way... BUG:243954 git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220223 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
BIN
tests/data/noise.aif
Normal file
BIN
tests/data/noise.aif
Normal file
Binary file not shown.
BIN
tests/data/noise_odd.aif
Normal file
BIN
tests/data/noise_odd.aif
Normal file
Binary file not shown.
@ -13,8 +13,10 @@ class PublicRIFF : public RIFF::File
|
||||
{
|
||||
public:
|
||||
PublicRIFF(FileName file) : RIFF::File(file, BigEndian) {};
|
||||
TagLib::uint riffSize() { return RIFF::File::riffSize(); };
|
||||
TagLib::uint chunkCount() { return RIFF::File::chunkCount(); };
|
||||
TagLib::uint chunkOffset(TagLib::uint i) { return RIFF::File::chunkOffset(i); };
|
||||
TagLib::uint chunkPadding(TagLib::uint i) { return RIFF::File::chunkPadding(i); };
|
||||
TagLib::uint chunkDataSize(TagLib::uint i) { return RIFF::File::chunkDataSize(i); };
|
||||
ByteVector chunkName(TagLib::uint i) { return RIFF::File::chunkName(i); };
|
||||
ByteVector chunkData(TagLib::uint i) { return RIFF::File::chunkData(i); };
|
||||
@ -30,6 +32,9 @@ class TestRIFF : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(TestRIFF);
|
||||
CPPUNIT_TEST(testPadding);
|
||||
CPPUNIT_TEST(testLastChunkAtEvenPosition);
|
||||
CPPUNIT_TEST(testLastChunkAtEvenPosition2);
|
||||
CPPUNIT_TEST(testLastChunkAtEvenPosition3);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
@ -77,6 +82,117 @@ public:
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("foo"), f->chunkData(2));
|
||||
}
|
||||
|
||||
void testLastChunkAtEvenPosition()
|
||||
{
|
||||
ScopedFileCopy copy("noise", ".aif");
|
||||
string filename = copy.fileName();
|
||||
|
||||
PublicRIFF *f = new PublicRIFF(filename.c_str());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0xff0 + 8), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(long(4400), f->length());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4399 - 8), f->riffSize());
|
||||
f->setChunkData("TEST", "abcd");
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4088), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4408), f->chunkOffset(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f->chunkDataSize(3));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0), f->chunkPadding(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4412 - 8), f->riffSize());
|
||||
delete f;
|
||||
|
||||
f = new PublicRIFF(filename.c_str());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4088), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4408), f->chunkOffset(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f->chunkDataSize(3));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0), f->chunkPadding(3));
|
||||
CPPUNIT_ASSERT_EQUAL(long(4412), f->length());
|
||||
delete f;
|
||||
}
|
||||
|
||||
void testLastChunkAtEvenPosition2()
|
||||
{
|
||||
ScopedFileCopy copy("noise_odd", ".aif");
|
||||
string filename = copy.fileName();
|
||||
|
||||
PublicRIFF *f = new PublicRIFF(filename.c_str());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0xff0 + 8), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(long(4399), f->length());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4399 - 8), f->riffSize());
|
||||
f->setChunkData("TEST", "abcd");
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4088), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4408), f->chunkOffset(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f->chunkDataSize(3));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0), f->chunkPadding(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4412 - 8), f->riffSize());
|
||||
delete f;
|
||||
|
||||
f = new PublicRIFF(filename.c_str());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4088), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4408), f->chunkOffset(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4), f->chunkDataSize(3));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0), f->chunkPadding(3));
|
||||
CPPUNIT_ASSERT_EQUAL(long(4412), f->length());
|
||||
delete f;
|
||||
}
|
||||
|
||||
void testLastChunkAtEvenPosition3()
|
||||
{
|
||||
ScopedFileCopy copy("noise_odd", ".aif");
|
||||
string filename = copy.fileName();
|
||||
|
||||
PublicRIFF *f = new PublicRIFF(filename.c_str());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0xff0 + 8), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(0), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(long(4399), f->length());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4399 - 8), f->riffSize());
|
||||
f->setChunkData("TEST", "abc");
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4088), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4408), f->chunkOffset(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), f->chunkDataSize(3));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4411 - 8), f->riffSize());
|
||||
delete f;
|
||||
|
||||
f = new PublicRIFF(filename.c_str());
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4088), f->chunkOffset(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(311), f->chunkDataSize(2));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("SSND"), f->chunkName(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(2));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(4408), f->chunkOffset(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(3), f->chunkDataSize(3));
|
||||
CPPUNIT_ASSERT_EQUAL(ByteVector("TEST"), f->chunkName(3));
|
||||
CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), f->chunkPadding(3));
|
||||
CPPUNIT_ASSERT_EQUAL(long(4412), f->length());
|
||||
delete f;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestRIFF);
|
||||
|
Reference in New Issue
Block a user