const unsigned int commentLength = data.toUInt(pos, false);
pos += 4;
- ByteVector entry = data.mid(pos, commentLength);
-
+ const ByteVector entry = data.mid(pos, commentLength);
pos += commentLength;
// Don't go past data end
+
if(pos > data.size())
break;
- // Handle Pictures separately
- if(entry.startsWith("METADATA_BLOCK_PICTURE=")) {
+ // Check for field separator
- // We need base64 encoded data including padding
- if((entry.size() - 23) > 3 && ((entry.size() - 23) % 4) == 0) {
+ const int sep = entry.find('=');
+ if(sep < 1) {
+ debug("Ogg::XiphComment::parse() - Discarding a field. Separator not found.");
+ continue;
+ }
- // Decode base64 picture data
- ByteVector picturedata = ByteVector::fromBase64(entry.mid(23));
- if(picturedata.size()) {
+ // Parse the key
- // Decode Flac Picture
- FLAC::Picture * picture = new FLAC::Picture();
- if(picture->parse(picturedata)) {
+ const String key = String(entry.mid(0, sep), String::UTF8).upper();
+ if(!checkKey(key)) {
+ debug("Ogg::XiphComment::parse() - Discarding a field. Invalid key.");
+ continue;
+ }
- d->pictureList.append(picture);
+ if(key == "METADATA_BLOCK_PICTURE" || key == "COVERART") {
- // continue to next field
- continue;
- }
- else {
- delete picture;
- debug("Failed to decode FlacPicture block");
- }
- }
- else {
- debug("Failed to decode base64 encoded data");
- }
- }
- else {
- debug("Invalid base64 encoded data");
- }
- }
+ // Handle Pictures separately
- // Handle old picture standard
- if(entry.startsWith("COVERART=")) {
+ const ByteVector picturedata = ByteVector::fromBase64(entry.mid(sep + 1));
+ if(picturedata.isEmpty()) {
+ debug("Ogg::XiphComment::parse() - Discarding a field. Invalid base64 data");
+ continue;
+ }
- if((entry.size() - 9) > 3 && ((entry.size() - 9) % 4) == 0) {
+ if(key[0] == L'M') {
- // Decode base64 picture data
- ByteVector picturedata = ByteVector::fromBase64(entry.mid(9));
- if (picturedata.size()) {
+ // Decode FLAC Picture
- // Assume it's some type of image file
- FLAC::Picture * picture = new FLAC::Picture();
- picture->setData(picturedata);
- picture->setMimeType("image/");
- picture->setType(FLAC::Picture::Other);
+ FLAC::Picture * picture = new FLAC::Picture();
+ if(picture->parse(picturedata)) {
d->pictureList.append(picture);
-
- // continue to next field
- continue;
}
else {
- debug("Failed to decode base64 encoded data");
+ delete picture;
+ debug("Ogg::XiphComment::parse() - Failed to decode FLAC Picture block");
}
}
else {
- debug("Invalid base64 encoded data");
+
+ // Assume it's some type of image file
+
+ FLAC::Picture * picture = new FLAC::Picture();
+ picture->setData(picturedata);
+ picture->setMimeType("image/");
+ picture->setType(FLAC::Picture::Other);
+ d->pictureList.append(picture);
}
}
+ else {
- // Check for field separator
- int sep = entry.find('=');
- if(sep < 1) {
- debug("Discarding invalid comment field.");
- continue;
- }
+ // Parse the text
- // Parse key and value
- String key = String(entry.mid(0, sep), String::UTF8);
- String value = String(entry.mid(sep + 1), String::UTF8);
- addField(key, value, false);
+ addField(key, String(entry.mid(sep + 1), String::UTF8), false);
+ }
}
}
CPPUNIT_TEST(testClearComment);
CPPUNIT_TEST(testRemoveFields);
CPPUNIT_TEST(testPicture);
+ CPPUNIT_TEST(testLowercaseFields);
CPPUNIT_TEST_SUITE_END();
public:
}
}
+ void testLowercaseFields()
+ {
+ const ScopedFileCopy copy("lowercase-fields", ".ogg");
+ {
+ Vorbis::File f(copy.fileName().c_str());
+ List<FLAC::Picture *> lst = f.tag()->pictureList();
+ CPPUNIT_ASSERT_EQUAL(String("TEST TITLE"), f.tag()->title());
+ CPPUNIT_ASSERT_EQUAL(String("TEST ARTIST"), f.tag()->artist());
+ CPPUNIT_ASSERT_EQUAL((unsigned int)1, lst.size());
+ f.save();
+ }
+ {
+ Vorbis::File f(copy.fileName().c_str());
+ CPPUNIT_ASSERT(f.find("METADATA_BLOCK_PICTURE") > 0);
+ }
+ }
+
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestXiphComment);