Partial protection against broken WMA files

This fixes the problem on the reported file, but in general this code
needs a lot more checks.

https://bugs.kde.org/show_bug.cgi?id=268401
This commit is contained in:
Lukáš Lalinský 2011-03-13 21:33:57 +01:00
parent b3ae839a38
commit d3e79ddc38
2 changed files with 65 additions and 13 deletions

View File

@ -319,7 +319,16 @@ void ASF::File::HeaderExtensionObject::parse(ASF::File *file, uint /*size*/)
long long dataPos = 0;
while(dataPos < dataSize) {
ByteVector guid = file->readBlock(16);
long long size = file->readQWORD();
if(guid.size() != 16) {
file->setValid(false);
break;
}
bool ok;
long long size = file->readQWORD(&ok);
if(!ok) {
file->setValid(false);
break;
}
BaseObject *obj;
if(guid == metadataGuid) {
obj = new MetadataObject();
@ -389,19 +398,37 @@ void ASF::File::read(bool /*readProperties*/, Properties::ReadStyle /*properties
ByteVector guid = readBlock(16);
if(guid != headerGuid) {
debug("ASF: Not an ASF file.");
setValid(false);
return;
}
d->tag = new ASF::Tag();
d->properties = new ASF::Properties();
d->size = readQWORD();
int numObjects = readDWORD();
bool ok;
d->size = readQWORD(&ok);
if(!ok) {
setValid(false);
return;
}
int numObjects = readDWORD(&ok);
if(!ok) {
setValid(false);
return;
}
seek(2, Current);
for(int i = 0; i < numObjects; i++) {
ByteVector guid = readBlock(16);
long size = (long)readQWORD();
if(guid.size() != 16) {
setValid(false);
break;
}
long size = (long)readQWORD(&ok);
if(!ok) {
setValid(false);
break;
}
BaseObject *obj;
if(guid == filePropertiesGuid) {
obj = new FilePropertiesObject();
@ -429,7 +456,12 @@ void ASF::File::read(bool /*readProperties*/, Properties::ReadStyle /*properties
bool ASF::File::save()
{
if(readOnly()) {
debug("ASF: File is read-only.");
debug("ASF::File::save() -- File is read only.");
return false;
}
if(!isValid()) {
debug("ASF::File::save() -- Trying to save invalid file.");
return false;
}
@ -491,27 +523,47 @@ bool ASF::File::save()
// protected members
////////////////////////////////////////////////////////////////////////////////
int ASF::File::readBYTE()
int ASF::File::readBYTE(bool *ok)
{
ByteVector v = readBlock(1);
if(v.size() != 1) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v[0];
}
int ASF::File::readWORD()
int ASF::File::readWORD(bool *ok)
{
ByteVector v = readBlock(2);
if(v.size() != 2) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toUShort(false);
}
unsigned int ASF::File::readDWORD()
unsigned int ASF::File::readDWORD(bool *ok)
{
ByteVector v = readBlock(4);
if(v.size() != 4) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toUInt(false);
}
long long ASF::File::readQWORD()
long long ASF::File::readQWORD(bool *ok)
{
ByteVector v = readBlock(8);
if(v.size() != 8) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toLongLong(false);
}

View File

@ -88,10 +88,10 @@ namespace TagLib {
private:
int readBYTE();
int readWORD();
unsigned int readDWORD();
long long readQWORD();
int readBYTE(bool *ok = 0);
int readWORD(bool *ok = 0);
unsigned int readDWORD(bool *ok = 0);
long long readQWORD(bool *ok = 0);
static ByteVector renderString(const String &str, bool includeLength = false);
String readString(int len);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);