Memory management and other fixes from James H.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 17 Jun 2009 20:01:45 +0000 (20:01 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 17 Jun 2009 20:01:45 +0000 (20:01 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/puzzles@8596 cda61777-01e9-0310-a592-d414129be87e

bridges.c
filling.c
galaxies.c
lightup.c
map.c
midend.c
net.c
pattern.c
solo.c

index 694f011..64501ef 100644 (file)
--- a/bridges.c
+++ b/bridges.c
@@ -2244,6 +2244,8 @@ static game_state *execute_move(game_state *state, char *move)
             if (sscanf(move, "%d,%d,%d,%d,%d%n",
                        &x1, &y1, &x2, &y2, &nl, &n) != 5)
                 goto badmove;
+            if (!INGRID(ret, x1, y1) || !INGRID(ret, x2, y2))
+                goto badmove;
             is1 = INDEX(ret, gridi, x1, y1);
             is2 = INDEX(ret, gridi, x2, y2);
             if (!is1 || !is2) goto badmove;
@@ -2253,6 +2255,8 @@ static game_state *execute_move(game_state *state, char *move)
             if (sscanf(move, "%d,%d,%d,%d%n",
                        &x1, &y1, &x2, &y2, &n) != 4)
                 goto badmove;
+            if (!INGRID(ret, x1, y1) || !INGRID(ret, x2, y2))
+                goto badmove;
             is1 = INDEX(ret, gridi, x1, y1);
             is2 = INDEX(ret, gridi, x2, y2);
             if (!is1 || !is2) goto badmove;
@@ -2261,6 +2265,8 @@ static game_state *execute_move(game_state *state, char *move)
             if (sscanf(move, "%d,%d%n",
                        &x1, &y1, &n) != 2)
                 goto badmove;
+            if (!INGRID(ret, x1, y1))
+                goto badmove;
             is1 = INDEX(ret, gridi, x1, y1);
             if (!is1) goto badmove;
             island_togglemark(is1);
index 0209062..a797d09 100644 (file)
--- a/filling.c
+++ b/filling.c
@@ -1138,7 +1138,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
 
 static game_state *execute_move(game_state *state, char *move)
 {
-    game_state *new_state;
+    game_state *new_state = NULL;
     const int sz = state->shared->params.w * state->shared->params.h;
 
     if (*move == 's') {
@@ -1149,18 +1149,18 @@ static game_state *execute_move(game_state *state, char *move)
     } else {
         int value;
         char *endptr, *delim = strchr(move, '_');
-        if (!delim) return NULL;
+        if (!delim) goto err;
         value = strtol(delim+1, &endptr, 0);
-        if (*endptr || endptr == delim+1) return NULL;
-        if (value < 0 || value > 9) return NULL;
+        if (*endptr || endptr == delim+1) goto err;
+        if (value < 0 || value > 9) goto err;
         new_state = dup_game(state);
         while (*move) {
             const int i = strtol(move, &endptr, 0);
-            if (endptr == move) return NULL;
-            if (i < 0 || i >= sz) return NULL;
+            if (endptr == move) goto err;
+            if (i < 0 || i >= sz) goto err;
             new_state->board[i] = value;
             if (*endptr == '_') break;
-            if (*endptr != ',') return NULL;
+            if (*endptr != ',') goto err;
             move = endptr + 1;
         }
     }
@@ -1181,6 +1181,10 @@ static game_state *execute_move(game_state *state, char *move)
     }
 
     return new_state;
+
+err:
+    if (new_state) free_game(new_state);
+    return NULL;
 }
 
 /* ----------------------------------------------------------------------
index b80515d..55efa94 100644 (file)
@@ -365,7 +365,7 @@ static char *game_text_format(game_state *state)
                 case s_tile:
                     if (sp->flags & F_TILE_ASSOC) {
                         space *dot = sp2dot(state, sp->x, sp->y);
-                        if (dot->flags & F_DOT)
+                        if (dot && dot->flags & F_DOT)
                             *p++ = (dot->flags & F_DOT_BLACK) ? 'B' : 'W';
                         else
                             *p++ = '?'; /* association with not-a-dot. */
@@ -1450,6 +1450,7 @@ generate:
                state = copy2;
            }
        }
+        sfree(posns);
     }
 #endif
 
index a4e983d..298b7e2 100644 (file)
--- a/lightup.c
+++ b/lightup.c
@@ -727,6 +727,7 @@ static void place_lights(game_state *state, random_state *rs)
         debug_state(state);
         assert(!"place_lights failed to resolve overlapping lights!");
     }
+    sfree(numindices);
 }
 
 /* Fills in all black squares with numbers of adjacent lights. */
diff --git a/map.c b/map.c
index e3ded28..12cf507 100644 (file)
--- a/map.c
+++ b/map.c
@@ -1373,6 +1373,7 @@ static int map_solver(struct solver_scratch *sc,
              */
         }
 
+        sfree(origcolouring);
         sfree(subcolouring);
         free_scratch(rsc);
 
@@ -1788,9 +1789,9 @@ static char *validate_desc(game_params *params, char *desc)
 
     map = snewn(2*wh, int);
     ret = parse_edge_list(params, &desc, map);
+    sfree(map);
     if (ret)
        return ret;
-    sfree(map);
 
     if (*desc != ',')
        return "Expected comma before clue list";
index df395e0..323ac97 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -947,6 +947,7 @@ int midend_num_presets(midend *me)
                    me->ourgame->encode_params(preset, TRUE);
                 me->npresets++;
             }
+            sfree(e);
         }
     }
 
diff --git a/net.c b/net.c
index 3c8a660..2b5275e 100644 (file)
--- a/net.c
+++ b/net.c
@@ -950,8 +950,10 @@ static void perturb(int w, int h, unsigned char *tiles, int wrapping,
     }
     sfree(perim2);
 
-    if (i == nperim)
+    if (i == nperim) {
+        sfree(perimeter);
        return;                        /* nothing we can do! */
+    }
 
     /*
      * Now we've constructed a new link, we need to find the entire
@@ -2195,7 +2197,7 @@ static char *interpret_move(game_state *state, game_ui *ui,
 static game_state *execute_move(game_state *from, char *move)
 {
     game_state *ret;
-    int tx, ty, n, noanim, orig;
+    int tx = -1, ty = -1, n, noanim, orig;
 
     ret = dup_game(from);
 
@@ -2244,6 +2246,7 @@ static game_state *execute_move(game_state *from, char *move)
        }
     }
     if (!noanim) {
+        if (tx == -1 || ty == -1) { free_game(ret); return NULL; }
        ret->last_rotate_x = tx;
        ret->last_rotate_y = ty;
     }
index 787e591..274fcdb 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -569,7 +569,7 @@ static char *validate_desc(game_params *params, char *desc)
         if (*desc && isdigit((unsigned char)*desc)) {
             do {
                 p = desc;
-                while (desc && isdigit((unsigned char)*desc)) desc++;
+                while (*desc && isdigit((unsigned char)*desc)) desc++;
                 n = atoi(p);
                 rowspace -= n+1;
 
@@ -620,7 +620,7 @@ static game_state *new_game(midend *me, game_params *params, char *desc)
         if (*desc && isdigit((unsigned char)*desc)) {
             do {
                 p = desc;
-                while (desc && isdigit((unsigned char)*desc)) desc++;
+                while (*desc && isdigit((unsigned char)*desc)) desc++;
                 state->rowdata[state->rowsize * i + state->rowlen[i]++] =
                     atoi(p);
             } while (*desc++ == '.');
diff --git a/solo.c b/solo.c
index fc2ac04..0970eda 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -582,7 +582,6 @@ static struct block_structure *dup_block_structure(struct block_structure *b)
        nb->blocks[i] = nb->blocks_data + i*nb->max_nr_squares;
 
 #ifdef STANDALONE_SOLVER
-    nb->blocknames = (char **)smalloc(b->c * b->r *(sizeof(char *)+80));
     memcpy(nb->blocknames, b->blocknames, b->c * b->r *(sizeof(char *)+80));
     {
        int i;
@@ -1697,7 +1696,10 @@ static void solver(int cr, struct block_structure *blocks,
     usage->cube = snewn(cr*cr*cr, unsigned char);
     usage->grid = grid;                       /* write straight back to the input */
     if (kgrid) {
-       int nclues = kblocks->nr_blocks;
+       int nclues;
+
+        assert(kblocks);
+        nclues = kblocks->nr_blocks;
        /*
         * Allow for expansion of the killer regions, the absolute
         * limit is obviously one region per square.
@@ -2589,6 +2591,8 @@ static void solver(int cr, struct block_structure *blocks,
               "one solution");
 #endif
 
+    sfree(usage->sq2region);
+    sfree(usage->regions);
     sfree(usage->cube);
     sfree(usage->row);
     sfree(usage->col);
@@ -2598,6 +2602,7 @@ static void solver(int cr, struct block_structure *blocks,
        free_block_structure(usage->extra_cages);
        sfree(usage->extra_clues);
     }
+    if (usage->kclues) sfree(usage->kclues);
     sfree(usage);
 
     solver_free_scratch(scratch);
@@ -3551,13 +3556,8 @@ static char *new_game_desc(game_params *params, random_state *rs,
 
     blocks = alloc_block_structure (c, r, area, cr, cr);
 
-    if (params->killer) {
-       kblocks = alloc_block_structure (c, r, area, cr, area);
-       kgrid = snewn(area, digit);
-    } else {
-       kblocks = NULL;
-       kgrid = NULL;
-    }
+    kblocks = NULL;
+    kgrid = (params->killer) ? snewn(area, digit) : NULL;
 
 #ifdef STANDALONE_SOLVER
     assert(!"This should never happen, so we don't need to create blocknames");
@@ -3587,6 +3587,7 @@ static char *new_game_desc(game_params *params, random_state *rs,
        make_blocks_from_whichblock(blocks);
 
        if (params->killer) {
+            if (kblocks) free_block_structure(kblocks);
            kblocks = gen_killer_cages(cr, rs, params->kdiff > DIFF_KSINGLE);
        }
 
@@ -3753,6 +3754,11 @@ static char *new_game_desc(game_params *params, random_state *rs,
     desc = encode_puzzle_desc(params, grid, blocks, kgrid, kblocks);
 
     sfree(grid);
+    free_block_structure(blocks);
+    if (params->killer) {
+        free_block_structure(kblocks);
+        sfree(kgrid);
+    }
 
     return desc;
 }
@@ -4150,6 +4156,7 @@ static void free_game(game_state *state)
     sfree(state->immutable);
     sfree(state->pencil);
     sfree(state->grid);
+    if (state->kgrid) sfree(state->kgrid);
     sfree(state);
 }