RIFF: Read INFO text that isn't valid UTF-8 as Latin-1 when UTF-8 is assumed (#1480)

When setAssumedCodePage(65001) supplies the charset for an INFO tag
whose file declares none, a field whose bytes are not valid UTF-8 is
now read as ISO 8859-1, the RIFF default, instead of as an empty
string. A code page the file declares is never second-guessed, and a
handler installed with setStringHandler() still takes precedence.
This commit is contained in:
Ryan Francesconi
2026-11-01 05:49:03 +01:00
committed by GitHub
parent 747c6ca126
commit 3bce7df062
3 changed files with 45 additions and 0 deletions
+28
View File
@@ -397,6 +397,7 @@ class TestWAV : public CppUnit::TestFixture
CPPUNIT_TEST(testInfoAssumedCodePageAcceptsUtf8);
CPPUNIT_TEST(testInfoAssumedCodePageWindows1252);
CPPUNIT_TEST(testInfoAssumedCodePageOnlyWhenUndeclared);
CPPUNIT_TEST(testInfoAssumedUtf8FallsBackToLatin1);
CPPUNIT_TEST(testInfoAssumedCodePageRejectsUnsupported);
#endif
CPPUNIT_TEST_SUITE_END();
@@ -1111,6 +1112,33 @@ public:
}
}
// An assumed UTF-8 is a hint, and a field that is not valid UTF-8 contradicts
// it. Such a field is read as the RIFF default ISO 8859-1 instead of as empty,
// field by field, while a file that declares UTF-8 itself is taken at its word.
void testInfoAssumedUtf8FallsBackToLatin1()
{
const RestoreAssumedCodePage restore;
RIFF::Info::Tag::setAssumedCodePage(65001);
{
ByteVectorStream stream(riffWithInfo({{"IART", ByteVector("Caf\xC3\xA9", 5)},
{"ICOP", ByteVector("\xA9 2019 BOOM", 11)}}));
RIFF::WAV::File f(&stream);
CPPUNIT_ASSERT(f.isValid());
CPPUNIT_ASSERT_EQUAL(String(L"Caf\xE9"), f.InfoTag()->artist());
CPPUNIT_ASSERT_EQUAL(String(L"\xA9 2019 BOOM"), f.InfoTag()->fieldText("ICOP"));
}
{
ByteVectorStream stream(riffWithInfo({{"ICOP", ByteVector("\xA9 2019 BOOM", 11)}},
65001));
RIFF::WAV::File f(&stream);
CPPUNIT_ASSERT(f.isValid());
CPPUNIT_ASSERT(f.InfoTag()->fieldText("ICOP").isEmpty());
}
}
// A code page this library cannot decode would quietly do nothing if it were
// accepted as the assumption, so it is refused and the previous one stays.
void testInfoAssumedCodePageRejectsUnsupported()