[Scummvm-cvs-logs] SF.net SVN: scummvm:[38925] scummvm/trunk/engines/sword1

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Fri Feb 27 06:52:22 CET 2009


Revision: 38925
          http://scummvm.svn.sourceforge.net/scummvm/?rev=38925&view=rev
Author:   eriktorbjorn
Date:     2009-02-27 05:52:22 +0000 (Fri, 27 Feb 2009)

Log Message:
-----------
Committed patch #2606844 ("Fix crash when using BS1 without portuguese data").
Admittedly, I'm not really that familiar with BS1 resource management, but as
far as I can tell the patch just adds sanity checking, so it shouldn't hurt.

Modified Paths:
--------------
    scummvm/trunk/engines/sword1/objectman.cpp
    scummvm/trunk/engines/sword1/resman.cpp

Modified: scummvm/trunk/engines/sword1/objectman.cpp
===================================================================
--- scummvm/trunk/engines/sword1/objectman.cpp	2009-02-27 05:22:16 UTC (rev 38924)
+++ scummvm/trunk/engines/sword1/objectman.cpp	2009-02-27 05:52:22 UTC (rev 38925)
@@ -101,7 +101,10 @@
 
 char *ObjectMan::lockText(uint32 textId) {
 	uint8 lang = SwordEngine::_systemVars.language;
-	char *addr = (char*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header);
+	char *addr = (char*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]);
+	if (addr == 0)
+		return _missingSubTitleStr;
+	addr += sizeof(Header);
 	if ((textId & ITM_ID) >= _resMan->readUint32(addr)) {
 		warning("ObjectMan::lockText(%d): only %d texts in file", textId & ITM_ID, _resMan->readUint32(addr));
 		textId = 0; // get first line instead

Modified: scummvm/trunk/engines/sword1/resman.cpp
===================================================================
--- scummvm/trunk/engines/sword1/resman.cpp	2009-02-27 05:22:16 UTC (rev 38924)
+++ scummvm/trunk/engines/sword1/resman.cpp	2009-02-27 05:52:22 UTC (rev 38925)
@@ -199,8 +199,12 @@
 
 void *ResMan::fetchRes(uint32 id) {
 	MemHandle *memHandle = resHandle(id);
+	if (!memHandle) {
+		warning("fetchRes:: resource %d out of bounds", id);
+		return NULL;
+	}
 	if (!memHandle->data)
-		error("fetchRes:: resource %d is not open!", id);
+		error("fetchRes:: resource %d is not open", id);
 	return memHandle->data;
 }
 
@@ -216,8 +220,10 @@
 	if (outf.open(outn)) {
 		resOpen(id);
 		MemHandle *memHandle = resHandle(id);
-		outf.write(memHandle->data, memHandle->size);
-		outf.close();
+		if (memHandle) {
+			outf.write(memHandle->data, memHandle->size);
+			outf.close();
+		}
 		resClose(id);
 	}
 }
@@ -244,11 +250,14 @@
 #else
 	openCptResourceLittleEndian(id);
 #endif
-	return resHandle(id)->data;
+	MemHandle *handle = resHandle(id);
+	return handle != NULL ? handle->data : NULL;
 }
 
 void ResMan::resOpen(uint32 id) {  // load resource ID into memory
 	MemHandle *memHandle = resHandle(id);
+	if (!memHandle)
+		return;
 	if (memHandle->cond == MEM_FREED) { // memory has been freed
 		uint32 size = resLength(id);
 		_memMan->alloc(memHandle, size);
@@ -270,6 +279,8 @@
 
 void ResMan::resClose(uint32 id) {
 	MemHandle *handle = resHandle(id);
+	if (!handle)
+		return;
 	if (!handle->refCount) {
 		warning("Resource Manager fail: unlocking object with refCount 0. Id: %d\n", id);
 	} else {
@@ -313,7 +324,6 @@
 		else
 			sprintf(fileName, "%s.CLU", _prj.clu[(id >> 24)-1].label);
 		cluster->file->open(fileName);
-
 		if (!cluster->file->isOpen()) {
 			char msg[512];
 			sprintf(msg, "Couldn't open game cluster file '%s'\n\nIf you are running from CD, please ensure you have read the ScummVM documentation regarding multi-cd games.", fileName);
@@ -340,6 +350,12 @@
 	uint8 cluster = (uint8)((id >> 24) - 1);
 	uint8 group = (uint8)(id >> 16);
 
+	// There is a know case of reading beyond array boundaries when trying to use
+	// portuguese subtitles (cluster file 2, group 6) with a version that do not
+	// contain subtitles for this languages (i.e. has only 6 languages and not 7).
+	if (cluster >= _prj.noClu || group >= _prj.clu[cluster].noGrp)
+		return NULL;	
+	
 	return &(_prj.clu[cluster].grp[group].resHandle[id & 0xFFFF]);
 }
 
@@ -349,6 +365,9 @@
 	uint8 cluster = (uint8)((id >> 24) - 1);
 	uint8 group = (uint8)(id >> 16);
 
+	if (cluster >= _prj.noClu || group >= _prj.clu[cluster].noGrp)
+		return 0;
+
 	return _prj.clu[cluster].grp[group].length[id & 0xFFFF];
 }
 
@@ -357,6 +376,9 @@
 		id = _srIdList[id & 0xFFFF];
 	uint8 cluster = (uint8)((id >> 24) - 1);
 	uint8 group = (uint8)(id >> 16);
+	
+	if (cluster >= _prj.noClu || group >= _prj.clu[cluster].noGrp)
+		return 0;
 
 	return _prj.clu[cluster].grp[group].offset[id & 0xFFFF];
 }
@@ -368,11 +390,14 @@
 		// If the resource are not in memory anymore, and therefore will be read
 		// from disk, they will need to be byte swaped.
 		MemHandle *memHandle = resHandle(id);
-		needByteSwap = (memHandle->cond == MEM_FREED);
+		if (memHandle)
+			needByteSwap = (memHandle->cond == MEM_FREED);
 	}
 	resOpen(id);
 	if (needByteSwap) {
 		MemHandle *handle = resHandle(id);
+		if (!handle)
+			return;
 		uint32 totSize = handle->size;
 		uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
 		totSize -= sizeof(Header);
@@ -393,11 +418,14 @@
 		// If the resource are not in memory anymore, and therefore will be read
 		// from disk, they will need to be byte swaped.
 		MemHandle *memHandle = resHandle(id);
-		needByteSwap = (memHandle->cond == MEM_FREED);
+		if (memHandle)
+			needByteSwap = (memHandle->cond == MEM_FREED);
 	}
 	resOpen(id);
 	if (needByteSwap) {
 		MemHandle *handle = resHandle(id);
+		if (!handle)
+			return;
 		uint32 totSize = handle->size;
 		uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
 		totSize -= sizeof(Header);
@@ -418,11 +446,14 @@
 		// If the resource are not in memory anymore, and therefore will be read
 		// from disk, they will need to be byte swaped.
 		MemHandle *memHandle = resHandle(id);
-		needByteSwap = (memHandle->cond == MEM_FREED);
+		if (memHandle)
+			needByteSwap = (memHandle->cond == MEM_FREED);
 	}
 	resOpen(id);
 	if (needByteSwap) {
 		MemHandle *handle = resHandle(id);
+		if (!handle)
+			return;
 		// uint32 totSize = handle->size;
 		Header *head = (Header*)handle->data;
 		head->comp_length = FROM_LE_32(head->comp_length);
@@ -447,11 +478,14 @@
 		// If the resource are not in memory anymore, and therefore will be read
 		// from disk, they will need to be byte swaped.
 		MemHandle *memHandle = resHandle(id);
-		needByteSwap = (memHandle->cond == MEM_FREED);
+		if (memHandle)
+			needByteSwap = (memHandle->cond == MEM_FREED);
 	}
 	resOpen(id);
 	if (needByteSwap) {
 		MemHandle *handle = resHandle(id);
+		if (!handle)
+			return;
 		// uint32 totSize = handle->size;
 		Header *head = (Header*)handle->data;
 		head->comp_length = FROM_BE_32(head->comp_length);


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