diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index 54f2b969..86f386db 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -677,7 +677,7 @@ void String::prepare(Type t) switch(t) { case UTF16: { - if(d->data.size() > 1) { + if(d->data.size() >= 1 && (d->data[0] == 0xfeff || d->data[0] == 0xfffe)) { bool swap = d->data[0] != 0xfeff; d->data.erase(d->data.begin(), d->data.begin() + 1); if(swap) { diff --git a/tests/test_id3v2.cpp b/tests/test_id3v2.cpp index 4ccdc9af..ed5e0b00 100644 --- a/tests/test_id3v2.cpp +++ b/tests/test_id3v2.cpp @@ -10,6 +10,7 @@ #include #include #include +#include "utils.h" using namespace std; using namespace TagLib; @@ -45,6 +46,7 @@ class TestID3v2 : public CppUnit::TestFixture CPPUNIT_TEST(testRenderUrlLinkFrame); CPPUNIT_TEST(testParseUserUrlLinkFrame); CPPUNIT_TEST(testRenderUserUrlLinkFrame); + CPPUNIT_TEST(testSaveUTF16Comment); CPPUNIT_TEST_SUITE_END(); public: @@ -243,6 +245,21 @@ public: CPPUNIT_ASSERT_EQUAL(String("Sunshine Superman"), f.ID3v2Tag()->frameListMap()["TIT2"].front()->toString()); } + void testSaveUTF16Comment() + { + String::Type defaultEncoding = ID3v2::FrameFactory::instance()->defaultTextEncoding(); + string newname = copyFile("xing", ".mp3"); + ID3v2::FrameFactory::instance()->setDefaultTextEncoding(String::UTF16); + MPEG::File foo(newname.c_str()); + foo.strip(); + foo.tag()->setComment("Test comment!"); + foo.save(); + MPEG::File bar(newname.c_str()); + CPPUNIT_ASSERT_EQUAL(String("Test comment!"), bar.tag()->comment()); + deleteFile(newname); + ID3v2::FrameFactory::instance()->setDefaultTextEncoding(defaultEncoding); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestID3v2); diff --git a/tests/test_string.cpp b/tests/test_string.cpp index 333a4180..ab331c89 100644 --- a/tests/test_string.cpp +++ b/tests/test_string.cpp @@ -34,6 +34,8 @@ class TestString : public CppUnit::TestFixture CPPUNIT_TEST(testString); CPPUNIT_TEST(testUTF16Encode); CPPUNIT_TEST(testUTF16Decode); + CPPUNIT_TEST(testUTF16DecodeInvalidBOM); + CPPUNIT_TEST(testUTF16DecodeEmptyWithBOM); CPPUNIT_TEST_SUITE_END(); public: @@ -108,6 +110,26 @@ public: CPPUNIT_ASSERT_EQUAL(a, String(d, String::UTF16)); } + // this test is expected to print "TagLib: String::prepare() - + // Invalid UTF16 string." on the console 3 times + void testUTF16DecodeInvalidBOM() + { + ByteVector b(" ", 1); + ByteVector c(" ", 2); + ByteVector d(" \0f\0o\0o", 8); + CPPUNIT_ASSERT_EQUAL(String(), String(b, String::UTF16)); + CPPUNIT_ASSERT_EQUAL(String(), String(c, String::UTF16)); + CPPUNIT_ASSERT_EQUAL(String(), String(d, String::UTF16)); + } + + void testUTF16DecodeEmptyWithBOM() + { + ByteVector a("\377\376", 2); + ByteVector b("\376\377", 2); + CPPUNIT_ASSERT_EQUAL(String(), String(a, String::UTF16)); + CPPUNIT_ASSERT_EQUAL(String(), String(b, String::UTF16)); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(TestString);