aboutsummaryrefslogtreecommitdiff
path: root/midend.c
diff options
context:
space:
mode:
authorBen Harris <bjh21@bjh21.me.uk>2022-10-16 18:31:54 +0100
committerBen Harris <bjh21@bjh21.me.uk>2022-10-16 19:02:14 +0100
commit02e5e93046d1ee2ce7acde629a6562db9b36fa5d (patch)
tree86deeb992d186c2fb4501882a7ae24f132ebfe98 /midend.c
parent879a6922b0c59108de91f191926d0dde62cd2bd6 (diff)
downloadpuzzles-02e5e93046d1ee2ce7acde629a6562db9b36fa5d.zip
puzzles-02e5e93046d1ee2ce7acde629a6562db9b36fa5d.tar.gz
puzzles-02e5e93046d1ee2ce7acde629a6562db9b36fa5d.tar.bz2
puzzles-02e5e93046d1ee2ce7acde629a6562db9b36fa5d.tar.xz
Add more validation to midend deserialisation routine
These are all pretty obvious and enforce constraints that would otherwise be enforced by segfault.
Diffstat (limited to 'midend.c')
-rw-r--r--midend.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/midend.c b/midend.c
index 4d0aa2c..10f6810 100644
--- a/midend.c
+++ b/midend.c
@@ -2265,15 +2265,15 @@ static const char *midend_deserialise_internal(
} else if (!strcmp(key, "TIME")) {
data.elapsed = (float)atof(val);
} else if (!strcmp(key, "NSTATES")) {
+ if (data.states) {
+ ret = "Two state counts provided in save file";
+ goto cleanup;
+ }
data.nstates = atoi(val);
if (data.nstates <= 0) {
ret = "Number of states in save file was negative";
goto cleanup;
}
- if (data.states) {
- ret = "Two state counts provided in save file";
- goto cleanup;
- }
data.states = snewn(data.nstates, struct midend_state_entry);
for (i = 0; i < data.nstates; i++) {
data.states[i].state = NULL;
@@ -2282,19 +2282,20 @@ static const char *midend_deserialise_internal(
}
} else if (!strcmp(key, "STATEPOS")) {
data.statepos = atoi(val);
- } else if (!strcmp(key, "MOVE")) {
- gotstates++;
- data.states[gotstates].movetype = MOVE;
- data.states[gotstates].movestr = val;
- val = NULL;
- } else if (!strcmp(key, "SOLVE")) {
- gotstates++;
- data.states[gotstates].movetype = SOLVE;
- data.states[gotstates].movestr = val;
- val = NULL;
- } else if (!strcmp(key, "RESTART")) {
+ } else if (!strcmp(key, "MOVE") ||
+ !strcmp(key, "SOLVE") ||
+ !strcmp(key, "RESTART")) {
+ if (!data.states) {
+ ret = "No state count provided in save file";
+ goto cleanup;
+ }
gotstates++;
- data.states[gotstates].movetype = RESTART;
+ if (!strcmp(key, "MOVE"))
+ data.states[gotstates].movetype = MOVE;
+ else if (!strcmp(key, "SOLVE"))
+ data.states[gotstates].movetype = SOLVE;
+ else
+ data.states[gotstates].movetype = RESTART;
data.states[gotstates].movestr = val;
val = NULL;
}
@@ -2305,12 +2306,20 @@ static const char *midend_deserialise_internal(
}
data.params = me->ourgame->default_params();
+ if (!data.parstr) {
+ ret = "Long-term parameters in save file are missing";
+ goto cleanup;
+ }
me->ourgame->decode_params(data.params, data.parstr);
if (me->ourgame->validate_params(data.params, true)) {
ret = "Long-term parameters in save file are invalid";
goto cleanup;
}
data.cparams = me->ourgame->default_params();
+ if (!data.cparstr) {
+ ret = "Short-term parameters in save file are missing";
+ goto cleanup;
+ }
me->ourgame->decode_params(data.cparams, data.cparstr);
if (me->ourgame->validate_params(data.cparams, false)) {
ret = "Short-term parameters in save file are invalid";
@@ -2340,6 +2349,10 @@ static const char *midend_deserialise_internal(
ret = "Game position in save file is out of range";
}
+ if (!data.states) {
+ ret = "No state count provided in save file";
+ goto cleanup;
+ }
data.states[0].state = me->ourgame->new_game(
me, data.cparams, data.privdesc ? data.privdesc : data.desc);