diff options
| author | Ben Harris <bjh21@bjh21.me.uk> | 2022-10-17 00:56:37 +0100 |
|---|---|---|
| committer | Ben Harris <bjh21@bjh21.me.uk> | 2022-10-20 23:58:34 +0100 |
| commit | 304796f9f184a783d0af21e445c690ed69de048b (patch) | |
| tree | 2e32e9a0b39651f6c2753e689032c909fcde3a73 /midend.c | |
| parent | 9f2eef876275a451b015c22961130b2e507ddd49 (diff) | |
| download | puzzles-304796f9f184a783d0af21e445c690ed69de048b.zip puzzles-304796f9f184a783d0af21e445c690ed69de048b.tar.gz puzzles-304796f9f184a783d0af21e445c690ed69de048b.tar.bz2 puzzles-304796f9f184a783d0af21e445c690ed69de048b.tar.xz | |
Hex-encode non-ASCII random seeds in save files
The developer documentation claims that save files are long ASCII
strings. This is mostly true, but there's nothing stopping a user
from entering non-ASCII characters as random seeds. The ASCII
property of save files is useful, so encode seeds in hex before
writing them unless they consist only of printable ASCII characters.
Hex-encoded seeds are written under a new key, HEXSEED, to distinguish
them from unencoded seeds. This means that old versions of the code
won't be able to load encoded seeds, but that's not a great loss:
seeds aren't generally portable between versions anyway.
Diffstat (limited to 'midend.c')
| -rw-r--r-- | midend.c | 32 |
1 files changed, 30 insertions, 2 deletions
@@ -2061,8 +2061,27 @@ void midend_serialise(midend *me, /* * The current game description, the privdesc, and the random seed. */ - if (me->seedstr) - wr("SEED", me->seedstr); + if (me->seedstr) { + /* + * Random seeds are not necessarily printable ASCII. + * Hex-encode the seed if necessary. Printable ASCII seeds + * are emitted unencoded for compatibility with older + * versions. + */ + int i; + + for (i = 0; me->seedstr[i]; i++) + if (me->seedstr[i] < 32 || me->seedstr[i] >= 127) + break; + if (me->seedstr[i]) { + char *hexseed = bin2hex((unsigned char *)me->seedstr, + strlen(me->seedstr)); + + wr("HEXSEED", hexseed); + sfree(hexseed); + } else + wr("SEED", me->seedstr); + } if (me->desc) wr("DESC", me->desc); if (me->privdesc) @@ -2264,6 +2283,15 @@ static const char *midend_deserialise_internal( sfree(data.cparstr); data.cparstr = val; val = NULL; + } else if (!strcmp(key, "HEXSEED")) { + unsigned char *tmp; + int len = strlen(val) / 2; /* length in bytes */ + tmp = hex2bin(val, len); + sfree(data.seed); + data.seed = snewn(len + 1, char); + memcpy(data.seed, tmp, len); + data.seed[len] = '\0'; + sfree(tmp); } else if (!strcmp(key, "SEED")) { sfree(data.seed); data.seed = val; |