]> granicus.if.org Git - taglib/commitdiff
Partial protection against broken WMA files
authorLukáš Lalinský <lalinsky@gmail.com>
Sun, 13 Mar 2011 20:33:57 +0000 (21:33 +0100)
committerLukáš Lalinský <lalinsky@gmail.com>
Sat, 19 Mar 2011 06:42:23 +0000 (07:42 +0100)
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
taglib/asf/asffile.h

index 0a947472a8751caa40b492a6b3516a98e4153c29..e39f856ff5d7d7f99940ac71af020dbf1703fe49 100644 (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);
 }
 
index 9242aa68df8a908b1699a60f515cd114f11a7eec..45e603dc0c656dbae5c1c84eb34f251ad7c6d43c 100644 (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);