diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp index 4ae40666..45ad0317 100644 --- a/taglib/toolkit/tbytevector.cpp +++ b/taglib/toolkit/tbytevector.cpp @@ -702,7 +702,14 @@ ByteVector &ByteVector::resize(uint size, char padding) { if(size != d->length) { detach(); + + // Remove the excessive length of the internal buffer first to pad correctly. + // This doesn't reallocate the buffer, since std::vector::resize() doesn't + // reallocate the buffer when shrinking. + + d->data->data.resize(d->offset + d->length); d->data->data.resize(d->offset + size, padding); + d->length = size; } diff --git a/tests/test_bytevector.cpp b/tests/test_bytevector.cpp index c68a8c34..de682084 100644 --- a/tests/test_bytevector.cpp +++ b/tests/test_bytevector.cpp @@ -42,6 +42,7 @@ class TestByteVector : public CppUnit::TestFixture CPPUNIT_TEST(testNumericCoversion); CPPUNIT_TEST(testReplace); CPPUNIT_TEST(testIterator); + CPPUNIT_TEST(testResize); CPPUNIT_TEST_SUITE_END(); public: @@ -334,6 +335,50 @@ public: CPPUNIT_ASSERT_EQUAL('3', *it4); } + void testResize() + { + ByteVector a = ByteVector("0123456789"); + ByteVector b = a.mid(3, 4); + b.resize(6, 'A'); + CPPUNIT_ASSERT_EQUAL(uint(6), b.size()); + CPPUNIT_ASSERT_EQUAL('6', b[3]); + CPPUNIT_ASSERT_EQUAL('A', b[4]); + CPPUNIT_ASSERT_EQUAL('A', b[5]); + b.resize(10, 'B'); + CPPUNIT_ASSERT_EQUAL(uint(10), b.size()); + CPPUNIT_ASSERT_EQUAL('6', b[3]); + CPPUNIT_ASSERT_EQUAL('B', b[6]); + CPPUNIT_ASSERT_EQUAL('B', b[9]); + b.resize(3, 'C'); + CPPUNIT_ASSERT_EQUAL(uint(3), b.size()); + CPPUNIT_ASSERT_EQUAL(-1, b.find('C')); + b.resize(3); + CPPUNIT_ASSERT_EQUAL(uint(3), b.size()); + + // Check if a and b were properly detached. + + CPPUNIT_ASSERT_EQUAL(uint(10), a.size()); + CPPUNIT_ASSERT_EQUAL('3', a[3]); + CPPUNIT_ASSERT_EQUAL('5', a[5]); + + // Special case that refCount == 1 and d->offset != 0. + + ByteVector c = ByteVector("0123456789").mid(3, 4); + c.resize(6, 'A'); + CPPUNIT_ASSERT_EQUAL(uint(6), c.size()); + CPPUNIT_ASSERT_EQUAL('6', c[3]); + CPPUNIT_ASSERT_EQUAL('A', c[4]); + CPPUNIT_ASSERT_EQUAL('A', c[5]); + c.resize(10, 'B'); + CPPUNIT_ASSERT_EQUAL(uint(10), c.size()); + CPPUNIT_ASSERT_EQUAL('6', c[3]); + CPPUNIT_ASSERT_EQUAL('B', c[6]); + CPPUNIT_ASSERT_EQUAL('B', c[9]); + c.resize(3, 'C'); + CPPUNIT_ASSERT_EQUAL(uint(3), c.size()); + CPPUNIT_ASSERT_EQUAL(-1, c.find('C')); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestByteVector);