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]); |