[Scummvm-cvs-logs] SF.net SVN: scummvm: [30834] scummvm/trunk/engines/kyra/resource.cpp

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Sat Feb 9 16:08:49 CET 2008


Revision: 30834
          http://scummvm.svn.sourceforge.net/scummvm/?rev=30834&view=rev
Author:   lordhoto
Date:     2008-02-09 07:08:49 -0800 (Sat, 09 Feb 2008)

Log Message:
-----------
Implemented proper PAK archive detector.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/resource.cpp

Modified: scummvm/trunk/engines/kyra/resource.cpp
===================================================================
--- scummvm/trunk/engines/kyra/resource.cpp	2008-02-09 14:43:43 UTC (rev 30833)
+++ scummvm/trunk/engines/kyra/resource.cpp	2008-02-09 15:08:49 UTC (rev 30834)
@@ -250,16 +250,14 @@
 			ResFileEntry entry;
 			entry.parent = "";
 			entry.size = temp.size();
-			entry.loadable = false;
+			entry.loadable = true;
 			entry.preload = false;
 			entry.prot = false;
-			entry.type = ResFileEntry::kPak;
+			entry.type = ResFileEntry::kAutoDetect;
 			entry.offset = 0;
 			_map[StaticResource::staticDataFilename()] = entry;
 			temp.close();
 		}
-	} else {
-		iter->_value.type = ResFileEntry::kPak;
 	}
 
 	detectFileTypes();
@@ -393,10 +391,47 @@
 };
 
 bool ResLoaderPak::isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const {
-	// TODO improve check:
-	Common::String file = filename;
-	file.toUppercase();
-	return ((file.hasSuffix(".PAK") && file != "TWMUSIC.PAK") || file.hasSuffix(".APK") || file.hasSuffix(".VRM") || file.hasSuffix(".TLK"));
+	uint32 filesize = stream.size();
+	uint32 offset = 0;
+	bool switchEndian = false;
+	bool firstFile = true;
+
+	offset = stream.readUint32LE();
+	if (offset > filesize) {
+		switchEndian = true;
+		offset = SWAP_BYTES_32(offset);
+	}
+
+	while (!stream.eos()) {
+		// The start offset of a file should never be in the filelist
+		if (offset < stream.pos() || offset > filesize)
+			return false;
+
+		Common::String file = "";
+		byte c = 0;
+
+		while (!stream.eos() && (c = stream.readByte()) != 0)
+			file += c;
+
+		if (stream.eos())
+			return false;
+
+		// Quit now if we encounter an empty string
+		if (file.empty()) {
+			if (firstFile)
+				return false;
+			else
+				break;
+		}
+
+		firstFile = false;
+		offset = switchEndian ? stream.readUint32BE() : stream.readUint32LE();
+
+		if (!offset || offset == filesize)
+			break;
+	}
+
+	return true;
 }
 
 bool ResLoaderPak::loadFile(const Common::String &filename, Common::SeekableReadStream &stream, ResFileMap &map) const {
@@ -407,6 +442,7 @@
 
 	uint32 startoffset = 0, endoffset = 0;
 	bool switchEndian = false;
+	bool firstFile = true;
 
 	startoffset = stream.readUint32LE();
 	if (startoffset > filesize) {
@@ -416,7 +452,7 @@
 
 	while (!stream.eos()) {
 		// The start offset of a file should never be in the filelist
-		if (startoffset < stream.pos()) {
+		if (startoffset < stream.pos() || startoffset > filesize) {
 			warning("PAK file '%s' is corrupted", filename.c_str());
 			return false;
 		}
@@ -433,9 +469,16 @@
 		}
 
 		// Quit now if we encounter an empty string
-		if (file.empty())
-			break;
+		if (file.empty()) {
+			if (firstFile) {
+				warning("PAK file '%s' is corrupted", filename.c_str());
+				return false;
+			} else {
+				break;
+			}
+		}
 
+		firstFile = false;
 		endoffset = switchEndian ? stream.readUint32BE() : stream.readUint32LE();
 
 		if (!endoffset)


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list