diff options
| -rw-r--r-- | common/macresman.cpp | 10 | ||||
| -rw-r--r-- | common/macresman.h | 2 | ||||
| -rw-r--r-- | common/md5.cpp | 28 | ||||
| -rw-r--r-- | common/md5.h | 31 | ||||
| -rw-r--r-- | engines/advancedDetector.cpp | 19 | ||||
| -rw-r--r-- | engines/agi/agi.cpp | 5 | ||||
| -rw-r--r-- | engines/agi/sound_2gs.cpp | 14 | ||||
| -rw-r--r-- | engines/kyra/staticres.cpp | 2 | ||||
| -rw-r--r-- | engines/lastexpress/debug.cpp | 5 | ||||
| -rw-r--r-- | engines/scumm/detection.cpp | 10 | ||||
| -rw-r--r-- | engines/scumm/file_nes.cpp | 22 | ||||
| -rw-r--r-- | engines/tinsel/detection.cpp | 8 | ||||
| -rw-r--r-- | test/common/md5.h | 4 | 
13 files changed, 86 insertions, 74 deletions
| diff --git a/common/macresman.cpp b/common/macresman.cpp index 641702b5ec..d268cfbf89 100644 --- a/common/macresman.cpp +++ b/common/macresman.cpp @@ -88,14 +88,12 @@ uint32 MacResManager::getResForkSize() {  	return _resForkSize;  } -bool MacResManager::getResForkMD5(char *md5str, uint32 length) { +Common::String MacResManager::computeResForkMD5AsString(uint32 length) {  	if (!hasResFork()) -		return false; +		return Common::String(); -	ReadStream *stream = new SeekableSubReadStream(_stream, _resForkOffset, _resForkOffset + _resForkSize); -	bool retVal = md5_file_string(*stream, md5str, MIN<uint32>(length, _resForkSize)); -	delete stream; -	return retVal; +	SeekableSubReadStream resForkStream(_stream, _resForkOffset, _resForkOffset + _resForkSize); +	return computeStreamMD5AsString(resForkStream, MIN<uint32>(length, _resForkSize));  }  bool MacResManager::open(Common::String filename) { diff --git a/common/macresman.h b/common/macresman.h index d47b0ca329..6b67b06bfb 100644 --- a/common/macresman.h +++ b/common/macresman.h @@ -82,7 +82,7 @@ public:  	Common::SeekableReadStream *getDataFork();  	Common::String getResName(uint32 typeID, uint16 resID);  	uint32 getResForkSize(); -	bool getResForkMD5(char *md5str, uint32 length); +	Common::String computeResForkMD5AsString(uint32 length = 0);  	Common::String getBaseFileName() { return _baseFileName; } diff --git a/common/md5.cpp b/common/md5.cpp index df544ca0f0..e4736e85ca 100644 --- a/common/md5.cpp +++ b/common/md5.cpp @@ -246,7 +246,7 @@ void md5_finish(md5_context *ctx, uint8 digest[16]) {  } -bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) { +bool computeStreamMD5(ReadStream &stream, uint8 digest[16], uint32 length) {  #ifdef DISABLE_MD5  	memset(digest, 0, 16); @@ -267,12 +267,14 @@ bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) {  	while ((i = stream.read(buf, readlen)) > 0) {  		md5_update(&ctx, buf, i); -		length -= i; -		if (restricted && length == 0) -			break; +		if (restricted) { +			length -= i; +			if (length == 0) +				break; -		if (restricted && sizeof(buf) > length) -			readlen = length; +			if (sizeof(buf) > length) +				readlen = length; +		}  	}  	md5_finish(&ctx, digest); @@ -280,16 +282,16 @@ bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) {  	return true;  } -bool md5_file_string(ReadStream &stream, char *md5str, uint32 length) { +String computeStreamMD5AsString(ReadStream &stream, uint32 length) { +	String md5;  	uint8 digest[16]; -	if (!md5_file(stream, digest, length)) -		return false; - -	for (int i = 0; i < 16; i++) { -		snprintf(md5str + i*2, 3, "%02x", (int)digest[i]); +	if (computeStreamMD5(stream, digest, length)) { +		for (int i = 0; i < 16; i++) { +			md5 += String::format("%02x", (int)digest[i]); +		}  	} -	return true; +	return md5;  }  } // End of namespace Common diff --git a/common/md5.h b/common/md5.h index 1fb937ae9b..29f3aeeb4c 100644 --- a/common/md5.h +++ b/common/md5.h @@ -26,18 +26,35 @@  #define COMMON_MD5_H  #include "common/scummsys.h" +#include "common/str.h"  namespace Common {  class ReadStream; -bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length = 0); - -// The following method work similar to the above one, but -// instead of computing the binary MD5 digest, it produces -// a human readable lowercase hexstring representing the digest. -// The md5str parameter must point to a buffer of 32+1 chars. -bool md5_file_string(ReadStream &stream, char *md5str, uint32 length = 0); +/** + * Compute the MD5 checksum of the content of the given ReadStream. + * The 128 bit MD5 checksum is returned directly in the array digest. + * If length is set to a positive value, then only the first length + * bytes of the stream are used to compute the checksum. + * @param[in] stream	the stream of whose data the MD5 is computed + * @param[out] digest	the computed MD5 checksum + * @param[in] length	the number of bytes for which to compute the checksum; 0 means all + * @return true on success, false if an error occurred + */ +bool computeStreamMD5(ReadStream &stream, uint8 digest[16], uint32 length = 0); + +/** + * Compute the MD5 checksum of the content of the given ReadStream. + * The 128 bit MD5 checksum is converted to a human readable + * lowercase hex string of length 32. + * If length is set to a positive value, then only the first length + * bytes of the stream are used to compute the checksum. + * @param[in] stream	the stream of whose data the MD5 is computed + * @param[in] length	the number of bytes for which to compute the checksum; 0 means all + * @return the MD5 as a hex string on success, and an empty string if an error occurred + */ +String computeStreamMD5AsString(ReadStream &stream, uint32 length = 0);  } // End of namespace Common diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index d48fd61118..9be406d714 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -357,7 +357,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)  struct SizeMD5 {  	int size; -	char md5[32+1]; +	Common::String md5;  };  typedef Common::HashMap<Common::String, SizeMD5, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SizeMD5Map; @@ -374,7 +374,7 @@ static void reportUnknown(const Common::FSNode &path, const SizeMD5Map &filesSiz  	printf("of the game you tried to add and its version/language/etc.:\n");  	for (SizeMD5Map::const_iterator file = filesSizeMD5.begin(); file != filesSizeMD5.end(); ++file) -		printf("  {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5, file->_value.size); +		printf("  {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5.c_str(), file->_value.size);  	printf("\n");  } @@ -459,10 +459,9 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p  				Common::MacResManager *macResMan = new Common::MacResManager();  				if (macResMan->open(parent, fname)) { -					if (!macResMan->getResForkMD5(tmp.md5, params.md5Bytes)) -						tmp.md5[0] = 0; +					tmp.md5 = macResMan->computeResForkMD5AsString(params.md5Bytes);  					tmp.size = macResMan->getResForkSize(); -					debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5); +					debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str());  					filesSizeMD5[fname] = tmp;  				} @@ -475,14 +474,12 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p  					if (testFile.open(allFiles[fname])) {  						tmp.size = (int32)testFile.size(); -						if (!md5_file_string(testFile, tmp.md5, params.md5Bytes)) -							tmp.md5[0] = 0; +						tmp.md5 = Common::computeStreamMD5AsString(testFile, params.md5Bytes);  					} else {  						tmp.size = -1; -						tmp.md5[0] = 0;  					} -					debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5); +					debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str());  					filesSizeMD5[fname] = tmp;  				}  			} @@ -523,8 +520,8 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p  				break;  			} -			if (fileDesc->md5 != NULL && 0 != strcmp(fileDesc->md5, filesSizeMD5[tstr].md5)) { -				debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesSizeMD5[tstr].md5); +			if (fileDesc->md5 != NULL && fileDesc->md5 != filesSizeMD5[tstr].md5) { +				debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesSizeMD5[tstr].md5.c_str());  				fileMissing = true;  				break;  			} diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index 4dcf5fee5e..cfe921a91e 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -459,9 +459,8 @@ int AgiEngine::agiLoadResource(int r, int n) {  	if (i == errOK && getGameID() == GID_GOLDRUSH && r == rPICTURE && n == 147 && _game.dirPic[n].len == 1982) {  		uint8 *pic = _game.pictures[n].rdata;  		Common::MemoryReadStream picStream(pic, _game.dirPic[n].len); -		char md5str[32+1]; -		Common::md5_file_string(picStream, md5str, _game.dirPic[n].len); -		if (scumm_stricmp(md5str, "1c685eb048656cedcee4eb6eca2cecea") == 0) { +		Common::String md5str = Common::computeStreamMD5AsString(picStream, _game.dirPic[n].len); +		if (md5str == "1c685eb048656cedcee4eb6eca2cecea") {  			pic[0x042] = 0x4B; // 0x49 -> 0x4B  			pic[0x043] = 0x66; // 0x26 -> 0x66  			pic[0x204] = 0x68; // 0x28 -> 0x68 diff --git a/engines/agi/sound_2gs.cpp b/engines/agi/sound_2gs.cpp index cc1cd0f6d5..2748344b36 100644 --- a/engines/agi/sound_2gs.cpp +++ b/engines/agi/sound_2gs.cpp @@ -855,11 +855,10 @@ bool SoundGen2GS::loadInstrumentHeaders(const Common::FSNode &exePath, const IIg  		// Check instrument set's md5sum  		data->seek(exeInfo.instSetStart); -		char md5str[32+1]; -		Common::md5_file_string(*data, md5str, exeInfo.instSet.byteCount); -		if (scumm_stricmp(md5str, exeInfo.instSet.md5)) { +		Common::String md5str = Common::computeStreamMD5AsString(*data, exeInfo.instSet.byteCount); +		if (md5str != exeInfo.instSet.md5) {  			warning("Unknown Apple IIGS instrument set (md5: %s) in %s, trying to use it nonetheless", -				md5str, exePath.getPath().c_str()); +				md5str.c_str(), exePath.getPath().c_str());  		}  		// Read in the instrument set one instrument at a time @@ -898,12 +897,11 @@ bool SoundGen2GS::loadWaveFile(const Common::FSNode &wavePath, const IIgsExeInfo  	// Check that we got the whole wave file  	if (uint8Wave && uint8Wave->size() == SIERRASTANDARD_SIZE) {  		// Check wave file's md5sum -		char md5str[32+1]; -		Common::md5_file_string(*uint8Wave, md5str, SIERRASTANDARD_SIZE); -		if (scumm_stricmp(md5str, exeInfo.instSet.waveFileMd5)) { +		Common::String md5str = Common::computeStreamMD5AsString(*uint8Wave, SIERRASTANDARD_SIZE); +		if (md5str != exeInfo.instSet.waveFileMd5) {  			warning("Unknown Apple IIGS wave file (md5: %s, game: %s).\n" \  				"Please report the information on the previous line to the ScummVM team.\n" \ -				"Using the wave file as it is - music may sound weird", md5str, exeInfo.exePrefix); +				"Using the wave file as it is - music may sound weird", md5str.c_str(), exeInfo.exePrefix);  		}  		uint8Wave->seek(0); // Seek wave to its start diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index cf270942bf..fe4bd2ad71 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -57,7 +57,7 @@ bool checkKyraDat(Common::SeekableReadStream *file) {  	uint8 digestCalc[16];  	file->seek(0, SEEK_SET); -	if (!Common::md5_file(*file, digestCalc, size)) +	if (!Common::computeStreamMD5(*file, digestCalc, size))  		return false;  	for (int i = 0; i < 16; ++i) diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp index 50f0109a3f..66949c3d34 100644 --- a/engines/lastexpress/debug.cpp +++ b/engines/lastexpress/debug.cpp @@ -281,9 +281,8 @@ bool Debugger::cmdDumpFiles(int argc, const char **) {  			restoreArchive(); \  			return true; \  		} \ -		char md5str[32+1]; \ -		Common::md5_file_string(*stream, md5str, (uint32)stream->size()); \ -		debugC(1, kLastExpressDebugResource, "%s, %d, %s", (*it)->getName().c_str(), stream->size(), (char *)&md5str); \ +		Common::String md5str = Common::computeStreamMD5AsString(*stream); \ +		debugC(1, kLastExpressDebugResource, "%s, %d, %s", (*it)->getName().c_str(), stream->size(), md5str.c_str()); \  		delete stream; \  	} \  } diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 467282bd43..10224d997d 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -422,7 +422,6 @@ static void composeFileHashMap(const Common::FSList &fslist, DescMap &fileMD5Map  static void detectGames(const Common::FSList &fslist, Common::List<DetectorResult> &results, const char *gameid) {  	DescMap fileMD5Map;  	DetectorResult dr; -	char md5str[32+1];  	// Dive one level down since mac indy3/loom has its files split into directories. See Bug #1438631  	composeFileHashMap(fslist, fileMD5Map, 2, directoryGlobs); @@ -479,10 +478,13 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul  				tmp->open(d.node);  			} -			if (tmp && tmp->isOpen() && Common::md5_file_string(*tmp, md5str, kMD5FileSizeLimit)) { +			Common::String md5str; +			if (tmp && tmp->isOpen()) +				md5str = computeStreamMD5AsString(*tmp, kMD5FileSizeLimit); +			if (!md5str.empty()) {  				d.md5 = md5str; -				d.md5Entry = findInMD5Table(md5str); +				d.md5Entry = findInMD5Table(md5str.c_str());  				dr.md5 = d.md5; @@ -494,7 +496,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul  					int filesize = tmp->size();  					if (d.md5Entry->filesize != filesize)  					debug(1, "SCUMM detector found matching file '%s' with MD5 %s, size %d\n", -						file.c_str(), md5str, filesize); +						file.c_str(), md5str.c_str(), filesize);  					// Sanity check: We *should* have found a matching gameid / variant at this point.  					// If not, then there's a bug in our data tables... diff --git a/engines/scumm/file_nes.cpp b/engines/scumm/file_nes.cpp index bfd45d8005..5403354830 100644 --- a/engines/scumm/file_nes.cpp +++ b/engines/scumm/file_nes.cpp @@ -1369,34 +1369,36 @@ bool ScummNESFile::generateIndex() {  bool ScummNESFile::open(const Common::String &filename) {  	if (_ROMset == kROMsetNum) { -		char md5str[32+1]; +		Common::String md5str;  		File f;  		f.open(filename); -		if (f.isOpen() && Common::md5_file_string(f, md5str)) { +		if (f.isOpen()) +			md5str = Common::computeStreamMD5AsString(f); +		if (!md5str.empty()) { -			if (!strcmp(md5str, "3905799e081b80a61d4460b7b733c206")) { +			if (md5str == "3905799e081b80a61d4460b7b733c206") {  				_ROMset = kROMsetUSA;  				debug(1, "ROM contents verified as Maniac Mansion (USA)"); -			} else if (!strcmp(md5str, "d8d07efcb88f396bee0b402b10c3b1c9")) { +			} else if (md5str == "d8d07efcb88f396bee0b402b10c3b1c9") {  				_ROMset = kROMsetEurope;  				debug(1, "ROM contents verified as Maniac Mansion (Europe)"); -			} else if (!strcmp(md5str, "22d07d6c386c9c25aca5dac2a0c0d94b")) { +			} else if (md5str == "22d07d6c386c9c25aca5dac2a0c0d94b") {  				_ROMset = kROMsetSweden;  				debug(1, "ROM contents verified as Maniac Mansion (Sweden)"); -			} else if (!strcmp(md5str, "81bbfa181184cb494e7a81dcfa94fbd9")) { +			} else if (md5str == "81bbfa181184cb494e7a81dcfa94fbd9") {  				_ROMset = kROMsetFrance;  				debug(2, "ROM contents verified as Maniac Mansion (France)"); -			} else if (!strcmp(md5str, "257f8c14d8c584f7ddd601bcb00920c7")) { +			} else if (md5str == "257f8c14d8c584f7ddd601bcb00920c7") {  				_ROMset = kROMsetGermany;  				debug(2, "ROM contents verified as Maniac Mansion (Germany)"); -			} else if (!strcmp(md5str, "f163cf53f7850e43fb482471e5c52e1a")) { +			} else if (md5str == "f163cf53f7850e43fb482471e5c52e1a") {  				_ROMset = kROMsetSpain;  				debug(2, "ROM contents verified as Maniac Mansion (Spain)"); -			} else if (!strcmp(md5str, "54a68a5f5e3c86da42b7ca5f51e79b1d")) { +			} else if (md5str == "54a68a5f5e3c86da42b7ca5f51e79b1d") {  				_ROMset = kROMsetItaly;  				debug(2, "ROM contents verified as Maniac Mansion (Italy)");  			} else { -				error("Unsupported Maniac Mansion ROM, md5: %s", md5str); +				error("Unsupported Maniac Mansion ROM, md5: %s", md5str.c_str());  				return false;  			}  		} else { diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp index cbd0ba267b..22e8806e7e 100644 --- a/engines/tinsel/detection.cpp +++ b/engines/tinsel/detection.cpp @@ -191,7 +191,7 @@ bool TinselMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGa  struct SizeMD5 {  	int size; -	char md5[32+1]; +	Common::String md5;  };  typedef Common::HashMap<Common::String, SizeMD5, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SizeMD5Map;  typedef Common::HashMap<Common::String, Common::FSNode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap; @@ -268,11 +268,9 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &  				if (testFile.open(allFiles[fname])) {  					tmp.size = (int32)testFile.size(); -					if (!md5_file_string(testFile, tmp.md5, detectionParams.md5Bytes)) -						tmp.md5[0] = 0; +					tmp.md5 = computeStreamMD5AsString(testFile, detectionParams.md5Bytes);  				} else {  					tmp.size = -1; -					tmp.md5[0] = 0;  				}  				filesSizeMD5[fname] = tmp; @@ -318,7 +316,7 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &  				break;  			} -			if (fileDesc->md5 != NULL && 0 != strcmp(fileDesc->md5, filesSizeMD5[tstr].md5)) { +			if (fileDesc->md5 != NULL && fileDesc->md5 != filesSizeMD5[tstr].md5) {  				fileMissing = true;  				break;  			} diff --git a/test/common/md5.h b/test/common/md5.h index c59b6dc853..f310845bb9 100644 --- a/test/common/md5.h +++ b/test/common/md5.h @@ -29,14 +29,14 @@ static const char *md5_test_digest[] = {  class MD5TestSuite : public CxxTest::TestSuite {  	public: -	void test_md5_file() { +	void test_computeStreamMD5() {  		int i, j;  		char output[33];  		unsigned char md5sum[16];  		for (i = 0; i < 7; i++) {  			Common::MemoryReadStream stream((const byte *)md5_test_string[i], strlen(md5_test_string[i])); -			Common::md5_file(stream, md5sum); +			Common::computeStreamMD5(stream, md5sum);  			for (j = 0; j < 16; j++) {  				sprintf(output + j * 2, "%02x", md5sum[j]); | 
