mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Add a fuzzing harness for Puzzles
This just feeds save files into the loading code, but because of how Puzzles is structured that actually exercises most of its parsers.
This commit is contained in:
@ -275,4 +275,9 @@ cliprogram(penrose-vector-test penrose.c COMPILE_DEFINITIONS TEST_VECTORS)
|
|||||||
cliprogram(sort-test sort.c COMPILE_DEFINITIONS SORT_TEST)
|
cliprogram(sort-test sort.c COMPILE_DEFINITIONS SORT_TEST)
|
||||||
cliprogram(tree234-test tree234.c COMPILE_DEFINITIONS TEST)
|
cliprogram(tree234-test tree234.c COMPILE_DEFINITIONS TEST)
|
||||||
|
|
||||||
|
write_generated_games_header()
|
||||||
|
cliprogram(fuzzpuzz fuzzpuzz.c list.c ${puzzle_sources}
|
||||||
|
COMPILE_DEFINITIONS COMBINED)
|
||||||
|
target_include_directories(fuzzpuzz PRIVATE ${generated_include_dir})
|
||||||
|
|
||||||
build_extras()
|
build_extras()
|
||||||
|
65
fuzzpuzz.c
Normal file
65
fuzzpuzz.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* fuzzpuzz.c: Fuzzing frontend to all puzzles.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The idea here is that this front-end supports all back-ends and can
|
||||||
|
* feed them save files. This tests the deserialiser, the code for
|
||||||
|
* loading game descriptions, and the processing of move strings,
|
||||||
|
* without all the tedium of actually rendering anything.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "puzzles.h"
|
||||||
|
|
||||||
|
static bool savefile_read(void *wctx, void *buf, int len)
|
||||||
|
{
|
||||||
|
FILE *fp = (FILE *)wctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = fread(buf, 1, len, fp);
|
||||||
|
return (ret == len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *err;
|
||||||
|
char *gamename;
|
||||||
|
int i;
|
||||||
|
const game * ourgame = NULL;
|
||||||
|
midend *me;
|
||||||
|
|
||||||
|
if (argc != 1) {
|
||||||
|
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = identify_game(&gamename, savefile_read, stdin);
|
||||||
|
if (err != NULL) {
|
||||||
|
fprintf(stderr, "%s\n", err);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < gamecount; i++)
|
||||||
|
if (strcmp(gamename, gamelist[i]->name) == 0)
|
||||||
|
ourgame = gamelist[i];
|
||||||
|
if (ourgame == NULL) {
|
||||||
|
fprintf(stderr, "Game '%s' not recognised\n", gamename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
me = midend_new(NULL, ourgame, NULL, NULL);
|
||||||
|
|
||||||
|
rewind(stdin);
|
||||||
|
err = midend_deserialise(me, savefile_read, stdin);
|
||||||
|
if (err != NULL) {
|
||||||
|
fprintf(stderr, "%s\n", err);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
midend_free(me);
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user