Make fromBase64 more strict and update code to follow taglib coding style

This commit is contained in:
Sander Jansen 2015-05-16 21:25:06 -05:00
parent c963d3ba04
commit f4c1beb161
2 changed files with 74 additions and 47 deletions

View File

@ -33,7 +33,7 @@
using namespace TagLib;
typedef List<FLAC::Picture*> PictureList;
typedef List<FLAC::Picture *> PictureList;
class Ogg::XiphComment::XiphCommentPrivate
{
@ -285,7 +285,7 @@ bool Ogg::XiphComment::contains(const String &key) const
void Ogg::XiphComment::removePicture(FLAC::Picture *picture, bool del)
{
List<FLAC::Picture *>::Iterator it = d->pictureList.find(picture);
PictureList::Iterator it = d->pictureList.find(picture);
if(it != d->pictureList.end())
d->pictureList.erase(it);
@ -410,9 +410,10 @@ void Ogg::XiphComment::parse(const ByteVector &data)
ByteVector entry = data.mid(pos, commentLength);
pos += commentLength;
// Don't go past data end
pos+=commentLength;
if (pos>data.size())
if (pos > data.size())
break;
// Handle Pictures separately
@ -421,12 +422,13 @@ void Ogg::XiphComment::parse(const ByteVector &data)
// Decode base64 picture data
ByteVector picturedata = ByteVector::fromBase64(entry.mid(23));
if(picturedata.size()==0) {
if(picturedata.size() == 0) {
debug("Empty picture data. Discarding content");
continue;
}
}
FLAC::Picture * picture = new FLAC::Picture();
if(picture->parse(picturedata))
d->pictureList.append(picture);
else
@ -436,11 +438,13 @@ void Ogg::XiphComment::parse(const ByteVector &data)
// Check for field separator
int sep = entry.find('=');
if (sep == -1)
break;
if (sep < 1) {
debug("Discarding invalid comment field.");
continue;
}
// Parse key and value
String key = String(entry.mid(0,sep), String::UTF8);
String key = String(entry.mid(0, sep), String::UTF8);
String value = String(entry.mid(sep+1), String::UTF8);
addField(key, value, false);
}

View File

@ -950,13 +950,9 @@ ByteVector ByteVector::toHex() const
return encoded;
}
ByteVector ByteVector::fromBase64(const ByteVector & input)
{
static const unsigned char base64[256]={
static const unsigned char base64[256] = {
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x3e,0x80,0x80,0x80,0x3f,
@ -980,61 +976,88 @@ ByteVector ByteVector::fromBase64(const ByteVector & input)
ByteVector output(len);
const unsigned char * src = (const unsigned char*) input.data();
unsigned char * dst = (unsigned char*)output.data();
while(4<=len) {
if(base64[src[0]]==0x80) break;
if(base64[src[1]]==0x80) break;
*dst++=((base64[src[0]]<<2)&0xfc)|((base64[src[1]]>>4)&0x03);
if(src[2]!='=') {
if(base64[src[2]]==0x80) break;
*dst++=((base64[src[1]]&0x0f)<<4)|((base64[src[2]]>>2)&0x0f);
if(src[3]!='=') {
if(base64[src[3]]==0x80) break;
*dst++=((base64[src[2]]&0x03)<<6)|(base64[src[3]]&0x3f);
unsigned char * dst = (unsigned char*) output.data();
while(4 <= len) {
// Check invalid character
if(base64[src[0]] == 0x80)
break;
// Check invalid character
if(base64[src[1]] == 0x80)
break;
// Decode first byte
*dst++ = ((base64[src[0]] << 2) & 0xfc) | ((base64[src[1]] >> 4) & 0x03);
if(src[2] != '=') {
// Check invalid character
if(base64[src[2]] == 0x80)
break;
// Decode second byte
*dst++ = ((base64[src[1]] & 0x0f) << 4) | ((base64[src[2]] >> 2) & 0x0f);
if(src[3] != '=') {
// Check invalid character
if(base64[src[3]] == 0x80)
break;
// Decode third byte
*dst++ = ((base64[src[2]] & 0x03) << 6) | (base64[src[3]] & 0x3f);
}
else {
// assume end of data
len -= 4;
break;
}
}
else {
// assume end of data
len -= 4;
break;
}
src+=4;
len-=4;
src += 4;
len -= 4;
}
output.resize(dst-(unsigned char*)output.data());
return output;
// Only return output if we processed all bytes
if(len == 0) {
output.resize(dst - (unsigned char*) output.data());
return output;
}
return ByteVector();
}
ByteVector ByteVector::toBase64() const
{
static const char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
if (size()) {
uint len=size();
ByteVector output(4 * ((len-1)/3+1)); // note roundup
uint len = size();
ByteVector output(4 * ((len - 1) / 3 + 1)); // note roundup
const char * src = data();
char * dst = output.data();
while(3<=len) {
*dst++=alphabet[(src[0]>>2)&0x3f];
*dst++=alphabet[((src[0]&0x03)<<4)|((src[1]>>4)&0x0f)];
*dst++=alphabet[((src[1]&0x0f)<<2)|((src[2]>>6)&0x03)];
*dst++=alphabet[src[2]&0x3f];
src+=3;
len-=3;
while(3 <= len) {
*dst++ = alphabet[(src[0] >> 2) & 0x3f];
*dst++ = alphabet[((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0f)];
*dst++ = alphabet[((src[1] & 0x0f) << 2) | ((src[2] >> 6) & 0x03)];
*dst++ = alphabet[src[2] & 0x3f];
src += 3;
len -= 3;
}
if(len) {
*dst++=alphabet[(src[0]>>2)&0x3f];
*dst++ = alphabet[(src[0] >> 2) & 0x3f];
if(len>1) {
*dst++=alphabet[((src[0]&0x03)<<4)|((src[1]>>4)&0x0f)];
*dst++=alphabet[((src[1]&0x0f)<<2)];
*dst++ = alphabet[((src[0] & 0x03) << 4)|((src[1] >> 4) & 0x0f)];
*dst++ = alphabet[((src[1] & 0x0f) << 2)];
}
else {
*dst++=alphabet[(src[0]&0x03)<<4];
*dst++='=';
*dst++ = alphabet[(src[0] & 0x03) << 4];
*dst++ = '=';
}
*dst++='=';
}