shithub: puzzles

Download patch

ref: 0a7c531e8f4c1970662f7c30aea006e65d5ff010
parent: 493bf16ddbe2185664d6c3053f7891a9f232c75c
author: Ben Harris <bjh21@bjh21.me.uk>
date: Mon Feb 13 05:04:47 EST 2023

Undead: check the return value of sscanf() in execute_move()

sscanf() assigns its output in order, so if a conversion specifier fails
to match, a later "%n" specifier will also not get its result assigned.
In Undead's execute_move(), this led to the result of "%n" being used
without being initialised.  That could cause it to try to parse
arbitrary memory as part of the move string, which shouldn't be a
security problem (since execute_move() handles untrusted input anyway),
but could lead to a crash and certainly wasn't helpful.

--- a/undead.c
+++ b/undead.c
@@ -2083,7 +2083,7 @@
         } else if (c == 'G' || c == 'V' || c == 'Z' || c == 'E' ||
                    c == 'g' || c == 'v' || c == 'z') {
             move++;
-            sscanf(move, "%d%n", &x, &n);
+            if (sscanf(move, "%d%n", &x, &n) != 1) goto badmove;
             if (x < 0 || x >= ret->common->num_total) goto badmove;
             if (c == 'G') ret->guess[x] = 1;
             if (c == 'V') ret->guess[x] = 2;