diff --git a/taglib/ogg/xiphcomment.cpp b/taglib/ogg/xiphcomment.cpp index 431c7980..6b87e3ea 100644 --- a/taglib/ogg/xiphcomment.cpp +++ b/taglib/ogg/xiphcomment.cpp @@ -33,7 +33,7 @@ using namespace TagLib; -typedef List PictureList; +typedef List 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::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); } diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp index 377dc034..14550ad1 100644 --- a/taglib/toolkit/tbytevector.cpp +++ b/taglib/toolkit/tbytevector.cpp @@ -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++='='; }