From 9a6d429a8372cc31fb1aa7de8e5f079a47ecf148 Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 17 Jun 2009 20:01:45 +0000 Subject: [PATCH] Memory management and other fixes from James H. git-svn-id: svn://svn.tartarus.org/sgt/puzzles@8596 cda61777-01e9-0310-a592-d414129be87e --- bridges.c | 6 ++++++ filling.c | 18 +++++++++++------- galaxies.c | 3 ++- lightup.c | 1 + map.c | 3 ++- midend.c | 1 + net.c | 7 +++++-- pattern.c | 4 ++-- solo.c | 25 ++++++++++++++++--------- 9 files changed, 46 insertions(+), 22 deletions(-) diff --git a/bridges.c b/bridges.c index 694f011..64501ef 100644 --- 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); diff --git a/filling.c b/filling.c index 0209062..a797d09 100644 --- 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; } /* ---------------------------------------------------------------------- diff --git a/galaxies.c b/galaxies.c index b80515d..55efa94 100644 --- a/galaxies.c +++ b/galaxies.c @@ -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 diff --git a/lightup.c b/lightup.c index a4e983d..298b7e2 100644 --- 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 --- 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"; diff --git a/midend.c b/midend.c index df395e0..323ac97 100644 --- 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 --- 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; } diff --git a/pattern.c b/pattern.c index 787e591..274fcdb 100644 --- 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 --- 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); } -- 2.11.0