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:
Ben Harris
2023-01-07 18:57:48 +00:00
parent 9478efe32e
commit 53a1faa0d7
2 changed files with 70 additions and 0 deletions

View File

@ -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
View 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;
}