diff options
author | Paul Gilbert | 2019-10-31 22:10:41 -0700 |
---|---|---|
committer | Paul Gilbert | 2019-11-11 18:20:29 -0800 |
commit | fdb5ead5ca91a92c11192e61d23beee90e4caacb (patch) | |
tree | 4bc6cf0c7400d3d0f41529fd63174e399f4970e6 | |
parent | d4cba56b418d04d6bca2ded3cabd3376aab5d3f3 (diff) | |
download | scummvm-rg350-fdb5ead5ca91a92c11192e61d23beee90e4caacb.tar.gz scummvm-rg350-fdb5ead5ca91a92c11192e61d23beee90e4caacb.tar.bz2 scummvm-rg350-fdb5ead5ca91a92c11192e61d23beee90e4caacb.zip |
GLK: ARCHETYPE: Fixes for string decryption
-rw-r--r-- | engines/glk/archetype/crypt.cpp | 57 | ||||
-rw-r--r-- | engines/glk/archetype/crypt.h | 5 | ||||
-rw-r--r-- | engines/glk/archetype/misc.cpp | 13 |
3 files changed, 55 insertions, 20 deletions
diff --git a/engines/glk/archetype/crypt.cpp b/engines/glk/archetype/crypt.cpp index d99dab0907..1b59163daf 100644 --- a/engines/glk/archetype/crypt.cpp +++ b/engines/glk/archetype/crypt.cpp @@ -28,10 +28,40 @@ namespace Archetype { byte CryptMask; EncryptionType Encryption; +static uint RandSeed; +const int RANDOM_KEY = 33797; void crypt_init() { Encryption = NONE; CryptMask = 0x55; + RandSeed = 0; +} + +static void setDecryptionSeed(uint new_seed) { + RandSeed = new_seed; +} + +static void cycleRandomSeed() { + uint16 c = RandSeed & 0xffff; + uint val = (uint)c * RANDOM_KEY; + c <<= 3; + c = (c & 0xff) | ((((c >> 8) + c) & 0xff) << 8); + val += (uint)c << 16; + + uint16 b = RandSeed >> 16; + val += (uint)b << 16; + b <<= 2; + val += (uint)b << 16; + val += (uint)(b & 0xff) << 24; + b <<= 5; + val += (uint)(b & 0xff) << 24; + + RandSeed = val + 1; +} + +static uint getDeterministicRandomNumber(uint limit) { + cycleRandomSeed(); + return (limit == 0) ? 0 : (RandSeed >> 16) % limit; } void cryptinit(EncryptionType crypt_kind, uint seed) { @@ -39,37 +69,38 @@ void cryptinit(EncryptionType crypt_kind, uint seed) { Encryption = crypt_kind; if (Encryption == COMPLEX) - g_vm->setRandomNumberSeed(seed); + setDecryptionSeed(seed); } -void cryptstr(Common::String &s) { +void cryptstr(char *buffer, size_t length) { byte nextMask; + char *p = buffer; switch (Encryption) { case SIMPLE: - for (uint i = 0; i < s.size(); ++i) - s.setChar(s[i] ^ CryptMask, i); + for (size_t i = 0; i < length; ++i, ++p) + *p ^= CryptMask; break; case PURPLE: - for (uint i = 0; i < s.size(); ++i) { - s.setChar(s[i] ^ CryptMask, i); - CryptMask += s[i] & 7; + for (size_t i = 0; i < length; ++i, ++p) { + *p ^= CryptMask; + CryptMask += *p & 7; } break; case UNPURPLE: - for (uint i = 0; i < s.size(); ++i) { - nextMask = CryptMask + (s[i] & 7); - s.setChar(s[i] ^ CryptMask, i); + for (size_t i = 0; i < length; ++i, ++p) { + nextMask = CryptMask + (*p & 7); + *p ^= CryptMask; CryptMask = nextMask; } break; case COMPLEX: - for (uint i = 0; i < s.size(); ++i) { - s.setChar(s[i] ^ CryptMask, i); - CryptMask = g_vm->getRandomNumber(0x100); + for (size_t i = 0; i < length; ++i, ++p) { + *p ^= CryptMask; + CryptMask = (byte)getDeterministicRandomNumber(0x100); } break; diff --git a/engines/glk/archetype/crypt.h b/engines/glk/archetype/crypt.h index d978210e9a..d92fe39cf6 100644 --- a/engines/glk/archetype/crypt.h +++ b/engines/glk/archetype/crypt.h @@ -23,8 +23,7 @@ #ifndef ARCHETYPE_CRYPT #define ARCHETYPE_CRYPT -#include "common/scummsys.h" -#include "common/str.h" +#include "glk/archetype/string.h" namespace Glk { namespace Archetype { @@ -56,7 +55,7 @@ extern void cryptinit(EncryptionType crypt_kind, uint seed); * if <method> is COMPLEX, a pseudorandom sequence is used to alter the * CryptMask.This can make prediction well-nigh impossible. */ -extern void cryptstr(Common::String &s); +extern void cryptstr(char *buffer, size_t length); } // End of namespace Archetype } // End of namespace Glk diff --git a/engines/glk/archetype/misc.cpp b/engines/glk/archetype/misc.cpp index e5a858ba00..c10bba1b33 100644 --- a/engines/glk/archetype/misc.cpp +++ b/engines/glk/archetype/misc.cpp @@ -155,11 +155,13 @@ String formatFilename(const String &name, const String &ext, bool replace) { void load_string(Common::ReadStream *fIn, String &the_string) { char buffer[257]; size_t strSize = fIn->readByte(); + (void)fIn->readByte(); // Redundant second copy of the length + fIn->read(buffer, strSize); buffer[strSize] = '\0'; + cryptstr(buffer, strSize); the_string = String(buffer); - cryptstr(the_string); } void dump_string(Common::WriteStream *fOut, const String &the_string) { @@ -170,9 +172,12 @@ void dump_string(Common::WriteStream *fOut, const String &the_string) { fOut->write(the_string.c_str(), the_string.size()); } else { - String tmp = the_string; - cryptstr(tmp); - fOut->write(tmp.c_str(), tmp.size()); + char buffer[257]; + strncpy(buffer, the_string.c_str(), 256); + buffer[256] = '\0'; + + cryptstr(buffer, the_string.size()); + fOut->write(buffer, the_string.size()); } } |