1817 Commits

Author SHA1 Message Date
68f9fae973 When loading, don't decode_ui unless we have a UI
If the save file doesn't have a UI line, it's not sensible to try to
decode it.
2023-01-15 16:24:27 +00:00
e5d106eb27 Don't allow negative clues in Pattern 2023-01-15 16:24:27 +00:00
38cf1955e5 Palisade: don't leak memory on a bad move
Invalid moves can turn up in corrupted save files, and puzzles
shouldn't leak memory when failing to load a corrupted save file.
2023-01-15 16:24:27 +00:00
c2eedeedfe Black Box: correct order of validation checks for "F" commands
It doesn't do much good to range-check an argument after using it as
an array index.
2023-01-15 16:24:27 +00:00
d5b8a20def Last-ditch point-count limit for Untangle
Anything over INT_MAX/3 will cause an integer overflow, so put the
limit there for now.
2023-01-15 16:24:27 +00:00
85ccdf2f75 Adjust Undead upper grid-size limit to avoid overflow 2023-01-15 16:24:27 +00:00
51dcf4add6 Last-ditch maximum size limit for Twiddle
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
c53e0d3867 Last-ditch maximum size limit for Tracks
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
07999443c2 Limit size of puzzle in Tents to avoid integer overflow 2023-01-15 16:24:27 +00:00
91d96fa0bc Last-ditch maximum size limit for Sixteen
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
5c36e1536a Last-ditch maximum size limit for Signpost
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
d5ec2758ee Last-ditch maximum size limit for Same Game
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
b090c82df1 Also limit Pegs to at least 1x1 even when not doing full validation 2023-01-15 16:24:27 +00:00
6e40605f1e Last-ditch maximum size limit for Pegs
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
8a3fb82e23 Last-ditch maximum size limit for Pearl
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
91c0fac1dc Last-ditch maximum size limit for Palisade
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
dd00e9c532 Integer overflow protection in Pattern
Both for grid sizes and for clue values.
2023-01-15 16:24:27 +00:00
40ec3aaf09 Last-ditch maximum size limit for Netslide
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
051357bb24 Last-ditch maximum size limit for Net
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
48e3452264 Avoid integer overflow in Mosaic maximum-size check 2023-01-15 16:24:27 +00:00
9e2e0692ed Also check for tiny grids in Mines
A zero-size grid isn't acceptable even if someone has generated it for
us.
2023-01-15 16:24:27 +00:00
5cc9bfb811 Last-ditch maximum size limit for Mines
This makes sure that width * height <= INT_MAX, which it rather needs
to be.  Also a similar check in decode_params when defaulting the
number of mines.
2023-01-15 16:24:27 +00:00
ed75535fc2 Last-ditch maximum size limit for Map
This makes sure that width * height <= INT_MAX, which it rather needs
to be.  Also a similar check in decode_params when defaulting the
number of regions.
2023-01-15 16:24:27 +00:00
261a9568fa Last-ditch maximum size limit for Magnets
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
d71bba1a17 Limit maximum grid size in Loopy
Every grid shape has its own limit, so this involved adding a new
interface between loopy.c and grid.c.  The limits are based on ensuring
that the co-ordinate system of the grid doesn't overflow INT_MAX and
neither do the lengths of the face and dot arrays.

Though now I come to look at it I think the actual limits of grid.c are
much lower.  Hmm.
2023-01-15 16:24:27 +00:00
fcda12f4b7 Last-ditch maximum size limit for Light Up
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
98724b9093 Last-ditch grid-size limit for Inertia
At least prevent integer overflow when constructing the grid.
2023-01-15 16:24:27 +00:00
d60192531e Insist that Flood grids must have non-zero size 2023-01-15 16:24:27 +00:00
da220a77d1 Last-ditch grid-size limit for Flood
At least prevent integer overflow when constructing the grid.
2023-01-15 16:24:27 +00:00
26d0633f87 Last-ditch maximum size limit for Flip
This makes sure that width * height <= INT_MAX, which it rather needs
to be.  Also in Flip's case that the square of the area still fits in
an int.
2023-01-15 16:24:27 +00:00
522588f699 Last-ditch grid-size limit for Fifteen
At least prevent integer overflow when constructing the grid.
2023-01-15 16:24:27 +00:00
d422dd6009 Last-ditch grid-size limit for Galaxies
At least prevent integer overflow when constructing the grid.
2023-01-15 16:24:27 +00:00
b3f3345764 Last-ditch grid-size limit for Dominosa
At least prevent integer overflow when constructing the grid.
2023-01-15 16:24:27 +00:00
97484b098f Last-ditch maximum size limit for Bridges
This makes sure that width * height <= INT_MAX, which it rather needs
to be.
2023-01-15 16:24:27 +00:00
21193eaf93 Palisade: forbid moves that remove grid edges
Without this check, a corrupt save file can include a move that
removes an edge of the grid, and then is_solved() walks off the edge
of the grid causing a buffer over- or under-run.

To demonstrate the bug, load this save file in a build with
AddressSanitizer:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :8:Palisade
PARAMS  :5:5x5n5
CPARAMS :5:5x5n5
DESC    :0:
NSTATES :1:2
STATEPOS:1:2
MOVE    :6:F0,0,1
2023-01-15 16:24:27 +00:00
b3d4a41979 Don't load too many states just because there's no STATEPOS
If we start seeing state records in a save file (MOVE, SOLVE, or
RESTART), we should already have seen STATEPOS, so emit an error if not.
This avoids the situation where we overrun the end of the state array
because we're continuing loading states in the hope a STATEPOS will come
along.  I've also added an assertion that we're not overrunning the
state array for added paranoia.

An earlier version of this fix just removed the test for data.statepos
at the head of the loop, but that's wrong for a file that only has the
initial state.

This bug can be demonstrated by building Bridges with AddressSanitizer
and loading this save file:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :7:Bridges
PARAMS  :13:7x7i30e10m2d0
CPARAMS :13:7x7i30e10m2d0
DESC    :24:a4b4a1g1a2a8a4a4m2b2b3e3
NSTATES :1:2
MOVE    :10:L1,0,4,0,1
MOVE    :10:L1,0,4,0,2
2023-01-15 16:21:37 +00:00
e5717d1ba2 Range-check record lengths when deserialising games
"1999999999999999999999999999999999999999999999999999" as a record
length should lead to an error, not a buffer overrun.

(fun fact that was less obvious to me than it should have been: very
large powers of ten are multiples of large powers of two, so that number
is -1 mod 2^32)

This bug can be demonstrated by building any puzzle with
AddressSanitizer and then loading this save file:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1999999999999999999999999999999999999999999999999999:1
2023-01-15 16:21:37 +00:00
942d883d9b Range-check normal moves in Undead
Normal moves shouldn't be allowed to write outside the board.  This
buffer overrun can be demonstrated by building Undead with
AddressSanitizer and loading this save file:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :6:Undead
PARAMS  :5:4x4dn
CPARAMS :5:4x4dn
DESC    :48:5,0,5,cRRaLRcLRc,0,2,1,3,1,0,0,3,4,3,2,3,4,2,1,1
NSTATES :1:2
STATEPOS:1:2
MOVE    :3:Z10
2023-01-15 16:21:37 +00:00
4845f3e913 Correct RANGECHECK macro in Black Box
Lasers are numbered from 0 to nlasers-1 inclusive, so the upper limit
should be "<", not "<=".
2023-01-15 16:21:37 +00:00
952ef8ca56 Undead: fix buffer overrun in "M" command
The guessable squares are numbered up to num_total, not "wh".  The
latter includes mirror squares that aren't included in the various
arrays describing the game state.

To reproduce the problem, build Undead with AddressSanitizer and press
"M".
2023-01-15 16:21:37 +00:00
a02c55b049 Undead: check for valid commands in execute_move()
Previously, Undead's execute_move would go into a spin when it
encountered an unexpected command character in a move string.  Now it
rejects the move instead.
2023-01-15 16:21:37 +00:00
023ce7554c Sixteen: limit length of moves
The code that actually executes the moves can only cope with moves of
at most the width (or height as appropriate) of the grid.  Reject any
longer move, and for symmetry also negative moves of the same
magnitude.

Without this, the tile-moving code tends to access off the start of the
tile array.  To demonstrate this, build Sixteen with AddressSanitizer
and load this save file:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :7:Sixteen
PARAMS  :3:4x4
CPARAMS :3:4x4
DESC    :38:2,16,3,10,13,8,7,4,9,14,12,11,15,1,5,6
NSTATES :1:2
STATEPOS:1:2
MOVE    :4:C1,9
2023-01-15 16:21:37 +00:00
1aded127eb Netslide: Reject moves wider than the grid
Also add a corresponding assertion to the underlying move primitive.
Without this limit, long moves cause a buffer overrun.

To demonstrate the problem, build Netslide with AddressSanitizer and
load this save file:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :8:Netslide
PARAMS  :3:4x4
CPARAMS :3:4x4
DESC    :16:49b59aca247714b4
NSTATES :1:2
STATEPOS:1:2
MOVE    :5:R3,51
2023-01-15 16:21:37 +00:00
a539f38efd Mosaic: reject game descriptions containing bad characters
Only numbers and lower-case letters are allowed.  Without this
restriction, a buffer overrun is possible.

To demonstrate the problem, load this save file into a build of Mosaic
with AddressSanitizer:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :6:Mosaic
PARAMS  :7:8x8a0h1
CPARAMS :7:8x8a0h1
DESC    :41:b2c3b~~2a5c6e3a55c6a5a4244e0c3a64d4b4232b
NSTATES :1:1
STATEPOS:1:1
2023-01-15 16:21:37 +00:00
5279fd24b2 Guess: validate peg colours in decode_ui()
Peg colours in the current guess must be within the range of colours
for the current game, just as they must be for completed moves.
Otherwise is_markable() can cause a buffer overrun.

Since there's no way for decode_ui() to report an error, it just ignores
the bad peg colours.  I've also added an assertion to catch this problem
in is_markable().

The following save file demonstrates the problem when loaded in a build
with AddressSanitizer:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :5:Guess
PARAMS  :9:c6p4g10Bm
CPARAMS :9:c6p4g10Bm
DESC    :8:2de917c0
UI      :7:7,7,7,7
NSTATES :1:1
STATEPOS:1:1
2023-01-15 16:21:37 +00:00
c84af670b5 Guess: Don't allow any moves once the game is solved
If the game is solved (either by a win or a loss), interpret_move()
can never return a move, but execute_move() should also reject any
moves in case we're loading a corrupt or malicious save file.
Otherwise a save file with more guesses than the maximum allowed can
cause a buffer overrun.

This save file demonstrates the problem when loaded into a build of
Puzzles with AddressSanitizer:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :5:Guess
PARAMS  :9:c6p4g1Bm
CPARAMS :9:c6p4g1Bm
DESC    :8:b5f3faed
NSTATES :1:3
STATEPOS:1:3
MOVE    :8:G1,1,2,2
MOVE    :8:G4,3,1,1
2023-01-15 16:21:37 +00:00
09b1629386 Fix Emscripten cmake setup after fuzzpuzz was added.
The call to cliprogram() doesn't actually add the target 'fuzzpuzz' on
that platform, so the subsequent target_include_directories fails. Fix
is to condition target_include_directories on the build_cli_programs
flag.
2023-01-15 16:18:05 +00:00
32c487ba57 Add a dictionary for AFL++
It consists of two parts.  One is the list of all record types used by
the serialiser, to make it easy for AFL++ to find them.  The other is
the "interesting" integers used by AFL++ converted to ASCII decimal
form because Puzzles save files are coded in decimal and this will
help AFL++ to guess good values.  I hope.
2023-01-12 22:21:45 +00:00
1a48d76fcc Remember to free the game name in fuzzpuzz 2023-01-12 22:21:45 +00:00
5fa1931560 Don't leak midends in fuzzpuzz
If deserialising a save file fails, the midend still needs to be freed.
2023-01-12 22:21:45 +00:00