shithub: puzzles

Download patch

ref: a98ac4bb428ab5c1ff665aa1def6cc14d02a4e19
parent: 1f72a1a2ecc89ba789a0b665a5e39da5febe27d2
author: Ben Harris <bjh21@bjh21.me.uk>
date: Fri Jan 27 19:45:38 EST 2023

Don't allow Bridges games with < 2 islands

Technically, a game with no islands is always solved, but it causes a
null-pointer dereference at startup because there's nowhere to put the
cursor.  Games with one island are always insoluble because the island
must have at least one bridge and there's nowhere for it to go.  So
the minimum playable game has two islands.

To demonstrate the segfault, try loading this save file:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :7:Bridges
PARAMS  :1:3
CPARAMS :1:3
DESC    :1:i
NSTATES :1:1
STATEPOS:1:1

--- a/bridges.c
+++ b/bridges.c
@@ -2007,15 +2007,15 @@
 
 static const char *validate_desc(const game_params *params, const char *desc)
 {
-    int i, wh = params->w * params->h;
+    int i, wh = params->w * params->h, nislands = 0;
 
     for (i = 0; i < wh; i++) {
         if (*desc >= '1' && *desc <= '9')
-            /* OK */;
+            nislands++;
         else if (*desc >= 'a' && *desc <= 'z')
             i += *desc - 'a'; /* plus the i++ */
         else if (*desc >= 'A' && *desc <= 'G')
-            /* OK */;
+            nislands++;
         else if (!*desc)
             return "Game description shorter than expected";
         else
@@ -2024,6 +2024,8 @@
     }
     if (*desc || i > wh)
         return "Game description longer than expected";
+    if (nislands < 2)
+        return "Game description has too few islands";
 
     return NULL;
 }