APE item keys should be ASCII between 0x20 and 0x7E, not UTF-8.

This commit is contained in:
Tsuda Kageyu
2016-02-01 22:19:43 +09:00
parent 8afbf6c92a
commit 92a1a00624
3 changed files with 29 additions and 9 deletions

View File

@ -34,7 +34,9 @@ using namespace APE;
class APE::Item::ItemPrivate
{
public:
ItemPrivate() : type(Text), readOnly(false) {}
ItemPrivate() :
type(Text),
readOnly(false) {}
Item::ItemTypes type;
String key;
@ -74,8 +76,9 @@ APE::Item::Item(const String &key, const ByteVector &value, bool binary) :
d->type = Binary;
d->value = value;
}
else
else {
d->text.append(value);
}
}
APE::Item::Item(const Item &item) :
@ -181,9 +184,8 @@ void APE::Item::appendValues(const StringList &values)
int APE::Item::size() const
{
// SFB: Why is d->key.size() used when size() returns the length in UniChars and not UTF-8?
int result = 8 + d->key.size() /* d->key.data(String::UTF8).size() */ + 1;
switch (d->type) {
int result = 8 + d->key.size() + 1;
switch(d->type) {
case Text:
if(!d->text.isEmpty()) {
StringList::ConstIterator it = d->text.begin();
@ -250,7 +252,9 @@ void APE::Item::parse(const ByteVector &data)
const unsigned int valueLength = data.toUInt(0, false);
const unsigned int flags = data.toUInt(4, false);
d->key = String(data.mid(8), String::UTF8);
// An item key can contain ASCII characters from 0x20 up to 0x7E, not UTF-8.
d->key = String(data.mid(8), String::Latin1);
const ByteVector value = data.mid(8 + d->key.size() + 1, valueLength);
@ -288,7 +292,7 @@ ByteVector APE::Item::render() const
data.append(ByteVector::fromUInt(value.size(), false));
data.append(ByteVector::fromUInt(flags, false));
data.append(d->key.data(String::UTF8));
data.append(d->key.data(String::Latin1));
data.append(ByteVector('\0'));
data.append(value);

View File

@ -43,6 +43,20 @@
using namespace TagLib;
using namespace APE;
namespace
{
inline bool isValidItemKey(const String &key)
{
for(String::ConstIterator it = key.begin(); it != key.end(); ++it) {
const int c = static_cast<unsigned short>(*it);
if(c < 0x20 || 0x7E < c)
return false;
}
return true;
}
}
class APE::Tag::TagPrivate
{
public:
@ -381,7 +395,8 @@ void APE::Tag::parse(const ByteVector &data)
APE::Item item;
item.parse(data.mid(pos));
d->itemListMap.insert(item.key().upper(), item);
if(isValidItemKey(item.key()))
d->itemListMap.insert(item.key().upper(), item);
pos += item.size();
}