diff --git a/taglib/asf/asfattribute.cpp b/taglib/asf/asfattribute.cpp index a4a4c178..85db872b 100644 --- a/taglib/asf/asfattribute.cpp +++ b/taglib/asf/asfattribute.cpp @@ -30,6 +30,7 @@ #ifdef WITH_ASF #include +#include #include "asfattribute.h" #include "asffile.h" @@ -197,6 +198,10 @@ ASF::Attribute::parse(ASF::File &f, int kind) name = f.readString(nameLength); } + if(kind != 2 && size > 65535) { + debug("ASF::Attribute::parse() -- Value larger than 64kB"); + } + switch(d->type) { case WordType: d->shortValue = f.readWORD(); @@ -232,6 +237,27 @@ ASF::Attribute::parse(ASF::File &f, int kind) return name; } +int +ASF::Attribute::dataSize() const +{ + switch (d->type) { + case WordType: + return 2; + case BoolType: + return 4; + case DWordType: + return 4; + case QWordType: + return 5; + case UnicodeType: + return d->stringValue.size() * 2 + 2; + case BytesType: + case GuidType: + return d->byteVectorValue.size(); + } + return 0; +} + ByteVector ASF::Attribute::render(const String &name, int kind) const { diff --git a/taglib/asf/asfattribute.h b/taglib/asf/asfattribute.h index 6c702c5d..97523894 100644 --- a/taglib/asf/asfattribute.h +++ b/taglib/asf/asfattribute.h @@ -165,6 +165,9 @@ namespace TagLib String parse(ASF::File &file, int kind = 0); #endif + //! Returns the size of the stored data + int dataSize() const; + private: friend class File; diff --git a/taglib/asf/asffile.cpp b/taglib/asf/asffile.cpp index e403934b..012f39b4 100644 --- a/taglib/asf/asffile.cpp +++ b/taglib/asf/asffile.cpp @@ -480,11 +480,12 @@ bool ASF::File::save() bool inMetadataObject = false; for(unsigned int j = 0; j < attributes.size(); j++) { const Attribute &attribute = attributes[j]; - if(!inExtendedContentDescriptionObject && attribute.language() == 0 && attribute.stream() == 0) { + bool largeValue = attribute.dataSize() > 65535; + if(!inExtendedContentDescriptionObject && !largeValue && attribute.language() == 0 && attribute.stream() == 0) { d->extendedContentDescriptionObject->attributeData.append(attribute.render(name)); inExtendedContentDescriptionObject = true; } - else if(!inMetadataObject && attribute.language() == 0 && attribute.stream() != 0) { + else if(!inMetadataObject && !largeValue && attribute.language() == 0 && attribute.stream() != 0) { d->metadataObject->attributeData.append(attribute.render(name, 1)); inMetadataObject = true; } diff --git a/tests/test_asf.cpp b/tests/test_asf.cpp index 16fae663..5094f0f0 100644 --- a/tests/test_asf.cpp +++ b/tests/test_asf.cpp @@ -19,6 +19,7 @@ class TestASF : public CppUnit::TestFixture CPPUNIT_TEST(testSaveStream); CPPUNIT_TEST(testSaveLanguage); CPPUNIT_TEST(testDWordTrackNumber); + CPPUNIT_TEST(testSaveLargeValue); CPPUNIT_TEST_SUITE_END(); public: @@ -122,6 +123,24 @@ public: delete f; } + void testSaveLargeValue() + { + ScopedFileCopy copy("silence-1", ".wma"); + string newname = copy.fileName(); + + ASF::File *f = new ASF::File(newname.c_str()); + ASF::AttributeList values; + ASF::Attribute attr(ByteVector(70000, 'x')); + values.append(attr); + f->tag()->attributeListMap()["WM/Blob"] = values; + f->save(); + delete f; + + f = new ASF::File(newname.c_str()); + CPPUNIT_ASSERT_EQUAL(ByteVector(70000, 'x'), f->tag()->attributeListMap()["WM/Blob"][0].toByteVector()); + delete f; + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestASF);