mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Merge the two versions of fuzzpuzz back together
Now there's a single version of the main loop that runs once in normal mode and repeatedly in AFL++ persistent mode. In persistent mode, fmemopen() allows the loop to read the shared-memory buffer as though it were a stdio stream. fmemopen() is POSIX-only, but so is AFL++.
This commit is contained in:
153
fuzzpuzz.c
153
fuzzpuzz.c
@ -13,78 +13,16 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef __AFL_FUZZ_TESTCASE_LEN
|
||||||
|
# include <unistd.h> /* read() is used by __AFL_FUZZ_TESTCASE_LEN. */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "puzzles.h"
|
#include "puzzles.h"
|
||||||
|
|
||||||
#ifdef __AFL_FUZZ_TESTCASE_LEN
|
#ifdef __AFL_FUZZ_INIT
|
||||||
/*
|
|
||||||
* AFL persistent mode, where we fuzz from a RAM buffer provided by
|
|
||||||
* AFL in a loop. This version can still be run standalone if
|
|
||||||
* necessary, for instance to diagnose a crash.
|
|
||||||
*/
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
__AFL_FUZZ_INIT();
|
__AFL_FUZZ_INIT();
|
||||||
|
|
||||||
struct memfile {
|
|
||||||
unsigned char *buf;
|
|
||||||
int off;
|
|
||||||
int len;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool memfile_read(void *wctx, void *buf, int len)
|
|
||||||
{
|
|
||||||
struct memfile *mem = (struct memfile *)wctx;
|
|
||||||
|
|
||||||
if (mem->len - mem->off < len) return false;
|
|
||||||
memcpy(buf, mem->buf + mem->off, min(len, mem->len - mem->off));
|
|
||||||
mem->off += len;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
const char *err;
|
|
||||||
char *gamename;
|
|
||||||
int i;
|
|
||||||
const game * ourgame = NULL;
|
|
||||||
midend *me;
|
|
||||||
struct memfile mem;
|
|
||||||
|
|
||||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
|
||||||
__AFL_INIT();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mem.buf = __AFL_FUZZ_TESTCASE_BUF;
|
|
||||||
while (__AFL_LOOP(10000)) {
|
|
||||||
|
|
||||||
mem.off = 0;
|
|
||||||
mem.len = __AFL_FUZZ_TESTCASE_LEN;
|
|
||||||
|
|
||||||
err = identify_game(&gamename, memfile_read, &mem);
|
|
||||||
if (err != NULL) continue;
|
|
||||||
|
|
||||||
for (i = 0; i < gamecount; i++)
|
|
||||||
if (strcmp(gamename, gamelist[i]->name) == 0)
|
|
||||||
ourgame = gamelist[i];
|
|
||||||
if (ourgame == NULL) continue;
|
|
||||||
|
|
||||||
me = midend_new(NULL, ourgame, NULL, NULL);
|
|
||||||
|
|
||||||
mem.off = 0;
|
|
||||||
|
|
||||||
err = midend_deserialise(me, memfile_read, &mem);
|
|
||||||
midend_free(me);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Standard mode, where we process a single save file from stdin.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool savefile_read(void *wctx, void *buf, int len)
|
static bool savefile_read(void *wctx, void *buf, int len)
|
||||||
{
|
{
|
||||||
FILE *fp = (FILE *)wctx;
|
FILE *fp = (FILE *)wctx;
|
||||||
@ -98,39 +36,66 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
const char *err;
|
const char *err;
|
||||||
char *gamename;
|
char *gamename;
|
||||||
int i;
|
int i, ret = -1;
|
||||||
const game * ourgame = NULL;
|
const game *ourgame = NULL;
|
||||||
midend *me;
|
midend *me;
|
||||||
|
FILE *in = NULL;
|
||||||
|
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
fprintf(stderr, "usage: %s\n", argv[0]);
|
fprintf(stderr, "usage: %s\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = identify_game(&gamename, savefile_read, stdin);
|
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||||
if (err != NULL) {
|
__AFL_INIT();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __AFL_FUZZ_TESTCASE_LEN
|
||||||
|
/*
|
||||||
|
* AFL persistent mode, where we fuzz from a RAM buffer provided
|
||||||
|
* by AFL in a loop. This version can still be run standalone if
|
||||||
|
* necessary, for instance to diagnose a crash.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (__AFL_LOOP(10000)) {
|
||||||
|
if (in != NULL) fclose(in);
|
||||||
|
in = fmemopen(__AFL_FUZZ_TESTCASE_BUF, __AFL_FUZZ_TESTCASE_LEN, "r");
|
||||||
|
if (in == NULL) {
|
||||||
|
fprintf(stderr, "fmemopen failed");
|
||||||
|
ret = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
in = stdin;
|
||||||
|
while (ret == -1) {
|
||||||
|
#endif
|
||||||
|
err = identify_game(&gamename, savefile_read, in);
|
||||||
|
if (err != NULL) {
|
||||||
|
fprintf(stderr, "%s\n", err);
|
||||||
|
ret = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
ret = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
me = midend_new(NULL, ourgame, NULL, NULL);
|
||||||
|
|
||||||
|
rewind(in);
|
||||||
|
err = midend_deserialise(me, savefile_read, in);
|
||||||
|
if (err != NULL) {
|
||||||
|
fprintf(stderr, "%s\n", err);
|
||||||
|
ret = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
midend_free(me);
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user