diff --git a/TODO b/TODO index 20994f5..78843e4 100644 --- a/TODO +++ b/TODO @@ -1,2 +1,9 @@ * Parallelise operations. * Only very basic support for [f]open/[f]read, etc. see fscanf, fgets... + +12:59 est-ce qu'il marcherait sur un socket +12:59 pas encore, mais c’est prévu +12:59 aussi il faudrait des options pour le déclencher qu'apres un + marker +12:59 genre dans la réponse HTTP, mais apres \r\n\r\n + diff --git a/src/fuzz.c b/src/fuzz.c index e0a2232..7088195 100644 --- a/src/fuzz.c +++ b/src/fuzz.c @@ -32,37 +32,41 @@ #include "random.h" #include "fuzz.h" -#define CHUNK_SIZE 1024 +#define MAGIC1 0x33ea84f7 +#define MAGIC2 0x783bc31f +/* We arbitrarily split files into 1024-byte chunks. Each chunk has an + * associated seed that can be computed from the zzuf seed, the chunk + * index and the fuzziness density. This allows us to predictably fuzz + * any part of the file without reading the whole file. */ +#define CHUNKSIZE 1024 void zzuf_fuzz(int fd, uint8_t *buf, uint64_t len) { - uint8_t bits[CHUNK_SIZE]; - uint64_t pos; - unsigned int i; + uint64_t start, stop; + unsigned int i, todo; - pos = files[fd].pos; + start = files[fd].pos; + stop = start + len; - for(i = pos / CHUNK_SIZE; - i < (pos + len + CHUNK_SIZE - 1) / CHUNK_SIZE; - i++) + for(i = start / CHUNKSIZE; i < (stop + CHUNKSIZE - 1) / CHUNKSIZE; i++) { - int todo; + uint32_t chunkseed = i * MAGIC1; - /* Add some random dithering to handle percent < 1.0/CHUNK_SIZE */ - zzuf_srand(_zzuf_seed ^ (i * 0x33ea84f7)); - todo = (int)((_zzuf_percent * CHUNK_SIZE + zzuf_rand(100)) / 100.0); - zzuf_srand(_zzuf_seed ^ (i * 0x7f48ae33) ^ (todo * 0x783bc31f)); + /* Add some random dithering to handle ratio < 1.0/CHUNKSIZE */ + zzuf_srand(_zzuf_seed ^ chunkseed); + todo = (int)((_zzuf_ratio * (CHUNKSIZE * 1000) + zzuf_rand(1000)) + / 1000.0); + zzuf_srand(_zzuf_seed ^ chunkseed ^ (todo * MAGIC2)); - memset(bits, 0, CHUNK_SIZE); while(todo--) { - uint64_t idx = i * CHUNK_SIZE + zzuf_rand(CHUNK_SIZE); + uint64_t idx = i * CHUNKSIZE + zzuf_rand(CHUNKSIZE); uint8_t byte = (1 << zzuf_rand(8)); - if(idx < pos || idx >= pos + len) + if(idx < start || idx >= stop) continue; - buf[idx - pos] ^= byte; + buf[idx - start] ^= byte; } } } diff --git a/src/libzzuf.c b/src/libzzuf.c index 4867d03..708219f 100644 --- a/src/libzzuf.c +++ b/src/libzzuf.c @@ -41,7 +41,7 @@ int _zzuf_ready = 0; int _zzuf_debug = 0; int _zzuf_seed = 0; -float _zzuf_percent = 0.04f; +float _zzuf_ratio = 0.057f; regex_t * _zzuf_include = NULL; regex_t * _zzuf_exclude = NULL; @@ -65,13 +65,13 @@ void zzuf_init(void) if(tmp && *tmp) _zzuf_seed = atol(tmp); - tmp = getenv("ZZUF_PERCENT"); + tmp = getenv("ZZUF_RATIO"); if(tmp && *tmp) - _zzuf_percent = atof(tmp); - if(_zzuf_percent < 0.0f) - _zzuf_percent = 0.0f; - else if(_zzuf_percent > 100.0f) - _zzuf_percent = 100.0f; + _zzuf_ratio = atof(tmp); + if(_zzuf_ratio < 0.0f) + _zzuf_ratio = 0.0f; + else if(_zzuf_ratio > 5.0f) + _zzuf_ratio = 5.0f; tmp = getenv("ZZUF_INCLUDE"); if(tmp && *tmp) diff --git a/src/libzzuf.h b/src/libzzuf.h index ba7c3ae..6824a85 100644 --- a/src/libzzuf.h +++ b/src/libzzuf.h @@ -30,7 +30,7 @@ extern struct zzuf files[]; extern int _zzuf_ready; extern int _zzuf_debug; extern int _zzuf_seed; -extern float _zzuf_percent; +extern float _zzuf_ratio; extern regex_t * _zzuf_include; extern regex_t * _zzuf_exclude; diff --git a/src/preload.c b/src/preload.c index 250d8de..c2a71c9 100644 --- a/src/preload.c +++ b/src/preload.c @@ -269,9 +269,9 @@ ssize_t read(int fd, void *buf, size_t count) files[fd].pos += ret; } - /* Sanity check */ + /* Sanity check, can be OK though (for instance with a character device) */ if((uint64_t)lseek64_orig(fd, 0, SEEK_CUR) != files[fd].pos) - fprintf(stderr, "ZZUF ERROR: OFFSET INCONSISTENCY\n"); + debug("warning: offset inconsistency"); return ret; } diff --git a/src/zzuf.c b/src/zzuf.c index 1355f13..a398482 100644 --- a/src/zzuf.c +++ b/src/zzuf.c @@ -54,18 +54,18 @@ int main(int argc, char *argv[]) /* Long option, needs arg, flag, short option */ { "include", 1, NULL, 'i' }, { "exclude", 1, NULL, 'e' }, - { "seed", 1, NULL, 's' }, - { "percent", 1, NULL, 'p' }, - { "debug", 1, NULL, 'd' }, - { "help", 0, NULL, 'h' }, + { "seed", 1, NULL, 's' }, + { "ratio", 1, NULL, 'r' }, + { "debug", 1, NULL, 'd' }, + { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'v' }, }; - int c = getopt_long(argc, argv, "i:e:s:p:dhv", + int c = getopt_long(argc, argv, "i:e:s:r:dhv", long_options, &option_index); # else # define MOREINFO "Try `%s -h' for more information.\n" - int c = getopt(argc, argv, "i:e:s:p:dhv"); + int c = getopt(argc, argv, "i:e:s:r:dhv"); # endif if(c == -1) break; @@ -81,8 +81,8 @@ int main(int argc, char *argv[]) case 's': /* --seed */ setenv("ZZUF_SEED", optarg, 1); break; - case 'p': /* --percent */ - setenv("ZZUF_PERCENT", optarg, 1); + case 'r': /* --ratio */ + setenv("ZZUF_RATIO", optarg, 1); break; case 'd': /* --debug */ setenv("ZZUF_DEBUG", "1", 1); @@ -156,8 +156,8 @@ static void version(void) #if defined(HAVE_GETOPT_H) static void usage(void) { - printf("Usage: zzuf [ -vdh ] [ -i regex ] [ -e regex ]\n"); - printf(" [ -p percent ] [ -s seed ] PROGRAM ARGS...\n"); + printf("Usage: zzuf [ -vdh ] [ -i include ] [ -e exclude ]\n"); + printf(" [ -r ratio ] [ -s seed ] PROGRAM ARGS...\n"); # ifdef HAVE_GETOPT_LONG printf(" -h, --help display this help and exit\n"); printf(" -v, --version output version information and exit\n");