From d3e79ddc389bf79ece829e5412cbbb8a5227ed6b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luk=C3=A1=C5=A1=20Lalinsk=C3=BD?= Date: Sun, 13 Mar 2011 21:33:57 +0100 Subject: [PATCH] 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 --- taglib/asf/asffile.cpp | 70 ++++++++++++++++++++++++++++++++++++------ taglib/asf/asffile.h | 8 ++--- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/taglib/asf/asffile.cpp b/taglib/asf/asffile.cpp index 0a947472..e39f856f 100644 --- a/taglib/asf/asffile.cpp +++ b/taglib/asf/asffile.cpp @@ -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); } diff --git a/taglib/asf/asffile.h b/taglib/asf/asffile.h index 9242aa68..45e603dc 100644 --- a/taglib/asf/asffile.h +++ b/taglib/asf/asffile.h @@ -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); -- 2.40.0