1851 Commits

Author SHA1 Message Date
87f21b2de4 Generate a possibly suitable marketing banner for the KaiStore
It wants a 240x130 pixel JPEG.  I've gone for rotating the screenshot
a bit because the store overlays text on the picture and I don't want
horizontal lines in the picture confusing the text.  I think the store
handles dimming the image, so the picture we produce is at full
brightness.
2023-01-19 20:34:48 +00:00
2a4abce8a8 kaios: Provide a populated "locales" field in the manifest
The documentation says it's only needed to override values in the main
manifest, but it's apparently required even if you only support one
locale.
2023-01-19 20:34:48 +00:00
fb13ce8d71 kaios: Turn off :hover highlighting in menus
Even when the virtual pointer is hidden in KaiOS, it still causes :hover
on whatever element is nominally under it, which is confusing.  Disable
all the :hover effects as a workaround.
2023-01-19 20:34:48 +00:00
eb60f001b7 Buildscr bits for making KaiOS builds
These are currently treated as just another JavaScript build, so they
don't have their own variable to turn them off.
2023-01-19 20:34:48 +00:00
cc2e94ab2b kaios: Put version numbers in manifest files
This only happens if something edits manifest.pl to provide a version
number, but Buildscr can do that.  KaiOS manifests are documented as
requiring dotted-decimal version numbers.  In fact, the restrictions are
much stricter than that, and unacceptable version numbers can break the
KaiStore developer portal. YY.MM.DD version numbers seem to be
acceptable.
2023-01-19 20:34:48 +00:00
1eba6388bf kaios: Hack out everything that needs dialogue boxes
They're proving to be a right nuisance and will probably require a
substantial overhaul to how they work across the entire JavaScript
front-end.  I don't think any of the functionality provided by the
dialogue boxes is critical, so in the interests of getting a minimum
viable product actually released I've disabled those features.

In most cases, this just involves commenting out bits of HTML.  The
"Custom..." menu item is added by C code, though, so there I've fallen
back to the standard Puzzles way to implement a nasty hack: an
environment variable.
2023-01-19 20:34:48 +00:00
81b6bccab6 js: Remove an outdated reference to the "invisible Custom option" 2023-01-19 20:34:48 +00:00
5ba1bf5560 js: Tolerate the absence of various UI elements from the HTML
To make things more consistent, the static buttons now all have their
own variables.
2023-01-19 20:34:48 +00:00
48ded126a9 js: Look up elements in the DOM as early as possible
Now that our script is loaded using <script defer>, we can rely on the
DOM's being complete as soon as it starts running.  So when we declare a
variable to point to a DOM element, we can initialise it with that
element.  This saves having these odd initialisations scattered around
the code, usually but not always at the site of first use.

I'd like to be able to do the same thing with the variables that point
to C functions, but the Module.cwrap() call isn't entirely safe before
Emscripten has finished loading the C code.
2023-01-19 20:34:48 +00:00
9d7b044c01 js: Simpler and more robust startup procedure
Previously, we initialised all of the JavaScript event handlers as soon
at the DOM was loaded, and then called main() ourselves once the
Emscripten runtime was ready.  This was slightly dangerous since it
depended on none of those event handlers' being called before main().
In practice this was difficult because most of the elements the event
handlers were attached to were invisible, but it did limit what event
handlers could safely be used.

Now, the event handlers are initialised from main().  This makes things
work in a sufficiently conventional way that we can just let the
Emscripten run-time call main() in its usual way, rather than involving
ourselves in the minutiae of Emscripten's startup.
2023-01-19 20:34:48 +00:00
420663d477 js: Use current_key_label() to label feature phone softkeys 2023-01-19 20:34:48 +00:00
e5604ccf37 js: Rename update_undo_redo() as post_move()
I want to do more things with it.
2023-01-19 20:34:48 +00:00
f693794ff5 js: Make soft-key labels generate key events when clicked
This makes the app page a little easier to test on desktop browsers that
don't have SoftLeft and SoftRight keys.
2023-01-19 20:34:48 +00:00
f9449af87a kaios: Major parts of a build for KaiOS
KaiOS (which is based on Firefox OS, formerly Boot to Gecko) runs its
"native" apps in a Web browser, so this is essentially a rather
specialised version of the JavaScript front-end.  Indeed, the JavaScript
and C parts are the same as the Web version.

There are three major parts that are specific to the KaiOS build.
First, there's manifest.pl, which generates a KaiOS-specific JSON
manifest describing each puzzle.

Second, there's a new HTML page generator, apppage.pl, that generates an
HTML page that is much less like a Web page, and much more like an
application, than the one generated by jspage.pl. It expects to build a
single HTML page at a time and gets all its limited knowledge of the
environment from its command line.  This makes it gratuitously different
from jspage.pl and javapage.pl, but makes it easier to run from the
build system.

And finally, there's the CMake glue that assembles the necessary parts
for each application in a directory.  This includes the manifest, the
HTML, the JavaScript, the KaiOS-specific icons (generated as part of the
GTK build) and a copy of the HTML documentation.  The directory is
assembled using CMake's install() function, and can be installed on a
KaiOS device using the developer tools.
2023-01-19 20:34:48 +00:00
241f68b543 Properly-styled icons for KaiOS
These are built alongside other icons as part of the GTK build.  It
builds new icon sizes of 44 and 88 pixels and then uses ImageMagick to
round off the corners and add a shadow in accordance with the KaiOS
design guide.
2023-01-19 20:34:48 +00:00
1d509dc819 js: Have the "SoftRight" key open the menu by focussing it 2023-01-19 20:34:48 +00:00
27c97c0ffd Allow repeated "solve" operations in Guess
Since using the "solve" option doesn't consume a guess, it's safe to
allow it to occur multiple times.  Without this, selecting "solve" a
second time causes an assertion failure because solve() returns a move
string that's rejected by execute_move().

Possible solve() could instead refuse to solve an already-solved
puzzle, but that seems needlessly pedantic.

[fixes c84af670b52f09e9e47587584c0559c508d4a37d]
2023-01-19 20:31:05 +00:00
b4aaa11943 Tracks: tighten up the 'illegal solve submoves' fix.
Chris mentioned in the commit message that there was a risk that
illegal moves might be permitted when playing on after a solve. So
I've changed the condition so that it depends only on whether the move
_currently being executed_ is a solve, rather than whether there was a
solve action anywhere in the undo history.

(Also, wrapped overlong lines while I was here.)
2023-01-19 12:47:55 +00:00
b5e02b0b9c Tracks: let solve make illegal moves
Not only does it set the outer edges to NOTRACK, but it may also overwrite
any mistakes the user has previously made elsewhere. Otherwise, the entire
solve is rejected ("Solve unavailable" error on Android) if the user has
made a single mistake, which is inconsistent with the other games.

This may be giving a free pass to corrupted moves that occur after a solve,
so this may still want tightening up in some way, but it's still limited to
squares within the grid, so I agree with Ben's assessment that this is
likely not to be exploitable.

Fixes #584

(cherry picked from Android port, commit
33bd14fb6f7cd760e7218fffd90f3a266b1f4123)
2023-01-19 00:21:27 +00:00
aaa36328dd Fix mosaic's validate_desc: 9 is valid
This rejected valid games that include a '9' clue.

Fixes Android issue #582.
2023-01-17 23:58:01 +00:00
80f64cfcda Avoid unnecessary timestamp bumps on generated-games.h.
If I re-run cmake in a Unix build directory, it unconditionally
rewrites generated-games.h, which causes fuzzpuzz to be rebuilt. This
is a waste of effort in the extremely common case where the rewritten
generated-games.h is identical to the old one.

Now we write the data to a temporary file first, and use cmake's
'configure_file' command to copy that to generated-games.h, because it
so happens that configure_file checks if the two files are identical
and avoids updating the timestamp on the destination file if so.

(This will presumably also be a beneficial change on any other
platform that uses generated_games.h in the build, such as OS X. I
just hadn't noticed until it hit the build I most often re-run in an
existing build directory.)

cmake 3.21 has a more intuitively spelled command I could have used,
called 'file(COPY_FILE src dst ONLY_IF_DIFFERENT)'. But we currently
permit cmake all the way back to 3.5, so I can't use that.
2023-01-17 19:04:22 +00:00
1dc1ed786f Fix memory leak in convert_tilesize
If old_dpr == new_dpr, convert_tilesize returns early without freeing
defaults.  Move the initialisation of defaults after this special
case.
2023-01-16 10:46:13 +00:00
4b5422181d Fix use-after-free in fuzzpuzz
When reporting that the game name in a save file isn't recognised,
don't include the name from the save file in the error message, partly
to avoid the complexity of freeing it properly on two different code
paths and partly because including unsanitized data from a
fuzzer-supplied save file in the error message just seems dangerous.
And properly sanitising it would waste the fuzzer's time exploring the
sanitising code.

Thanks to Ben Hutchings for reporting the bug.
2023-01-16 10:43:41 +00:00
f5924fc8a7 Correct syntax of fuzzpuzz.dict 2023-01-15 20:59:22 +00:00
5782e29db4 Tracks: make sure moves are valid in execute_move()
Tracks allowed moves in execute_move() that shouldn't have been allowed,
like changing the state of the edges of the board.  This moves couldn't
be generated by interpret_move(), but could be loaded from a save file.
Now execute_move() uses the same ui_can_flip_*() functions as
interpret_move() to decide whether a particular move is allowed.  This
should prevent some assertion failures when loading corrupted save
files.
2023-01-15 16:24:27 +00:00
15974d06bb Towers: reject descriptions with odd characters at the end
Towers' new_game() causes an assertion failure on game description
strings that contain spurious characters after a valid description, so
validate_desc() should also refuse such a description.  The problem
could be demonstrated by editing the game description in the
"Specific" dialogue box to add a '!' at the end, which caused
"new_game: Assertion `!*p' failed.".
2023-01-15 16:24:27 +00:00
5bd02f982a Mines: No moving once you're dead!
If a Mines save file contains a move after the player has already
died, this can lead to an assertion failure once there are more mines
that covered squares.  Better to just reject any move after the
player's died.
2023-01-15 16:24:27 +00:00
d3290195da Untangle: forbid descriptions that connect a node to itself
These cause an assertion failure in new_game(), so they should be
rejected by validate_desc().
2023-01-15 16:24:27 +00:00
ba944f9f95 Tighten Bridges' validate_desc()
It allowed V, W, X, Y, H, I, J, and K to appear in game descriptions
even though new_game() didn't ascribe any meaning to those letters and
would fail an assertion if they ever occurred.  As far as I can tell,
those letters have never done anything, so I've just removed the
checks for them from validate_desc().
2023-01-15 16:24:27 +00:00
8a06ff26fc Filling: validate length of auto-solve move strings
Without this, execute_move() can end up reading off the end of the
move string, which isn't very friendly.  Also remove the comment
saying that the move string doesn't have to be null-terminated,
because now it does.
2023-01-15 16:24:27 +00:00
a45f1830cf Explain what decode_ui() should do with invalid input
It can't signal an error, but it's worth documenting that it can
receive invalid input and should do what it can with it.  I assume
that failing to decode game_ui data from a newer version generally
won't be disastrous the way failing to decode a description or move
string would be.
2023-01-15 16:24:27 +00:00
8c5279cf75 Same Game: reject moves with unexpected characters in
Previously if a move string starting with "M" contained anything else
other than a digit or a comma, execute_move() would spin trying to
parse it.  Now it returns NULL.
2023-01-15 16:24:27 +00:00
0dbbd52935 Palisade: remove assertion from decode_ui()
Other games tolerate receiving an encoded game_ui even if they can
never generate one.  This is sensible, since it means that if a new
version starts saving UI state, old versions can load save files
generated by those newer versions.
2023-01-15 16:24:27 +00:00
e616d7aac9 Mosaic: fault out-of-bounds moves in execute_move()
Returning NULL in this case is better than dereferencing it.
2023-01-15 16:24:27 +00:00
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