diff --git a/unittests/test_helper/fuzz.c b/unittests/test_helper/fuzz.c index 72090f6..4f14217 100644 --- a/unittests/test_helper/fuzz.c +++ b/unittests/test_helper/fuzz.c @@ -45,6 +45,10 @@ /* For brevity later */ typedef unsigned long long fuzz_ullong; +/* For base-64 fuzzing */ +static const char fuzz_b64chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + struct fuzz { /* Fuzz method currently in use */ int strategy; @@ -81,6 +85,8 @@ fuzz_ntop(u_int n) return "FUZZ_TRUNCATE_START"; case FUZZ_TRUNCATE_END: return "FUZZ_TRUNCATE_END"; + case FUZZ_BASE64: + return "FUZZ_BASE64"; default: abort(); } @@ -127,6 +133,14 @@ fuzz_dump(struct fuzz *fuzz) fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen, fuzz->o1); break; + case FUZZ_BASE64: + assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); + fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n", + fuzz_ntop(fuzz->strategy), + (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, + fuzz->slen * (fuzz_ullong)64, fuzz->o1, + fuzz_b64chars[fuzz->o2]); + break; default: abort(); } @@ -198,12 +212,12 @@ fuzz_strategy_done(struct fuzz *fuzz) return fuzz->o1 >= fuzz->slen * 8; case FUZZ_2_BIT_FLIP: return fuzz->o2 >= fuzz->slen * 8; - case FUZZ_1_BYTE_FLIP: - return fuzz->o1 >= fuzz->slen; case FUZZ_2_BYTE_FLIP: return fuzz->o2 >= fuzz->slen; + case FUZZ_1_BYTE_FLIP: case FUZZ_TRUNCATE_START: case FUZZ_TRUNCATE_END: + case FUZZ_BASE64: return fuzz->o1 >= fuzz->slen; default: abort(); @@ -287,6 +301,17 @@ fuzz_next(struct fuzz *fuzz) memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); fuzz->o1++; break; + case FUZZ_BASE64: + assert(fuzz->o1 < fuzz->slen); + assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); + memcpy(fuzz->fuzzed, fuzz->seed, fuzz->slen); + fuzz->fuzzed[fuzz->o1] = fuzz_b64chars[fuzz->o2]; + fuzz->o2++; + if (fuzz->o2 >= sizeof(fuzz_b64chars) - 1) { + fuzz->o2 = 0; + fuzz->o1++; + } + break; default: abort(); } @@ -314,6 +339,7 @@ fuzz_len(struct fuzz *fuzz) case FUZZ_2_BIT_FLIP: case FUZZ_1_BYTE_FLIP: case FUZZ_2_BYTE_FLIP: + case FUZZ_BASE64: return fuzz->slen; case FUZZ_TRUNCATE_START: case FUZZ_TRUNCATE_END: @@ -333,6 +359,7 @@ fuzz_ptr(struct fuzz *fuzz) case FUZZ_2_BIT_FLIP: case FUZZ_1_BYTE_FLIP: case FUZZ_2_BYTE_FLIP: + case FUZZ_BASE64: return fuzz->fuzzed; case FUZZ_TRUNCATE_START: assert(fuzz->o1 <= fuzz->slen); diff --git a/unittests/test_helper/test_helper.h b/unittests/test_helper/test_helper.h index 6295bbe..d93ab73 100644 --- a/unittests/test_helper/test_helper.h +++ b/unittests/test_helper/test_helper.h @@ -264,7 +264,8 @@ struct fuzz; #define FUZZ_2_BYTE_FLIP 0x00000008 /* Flip two bytes at a time */ #define FUZZ_TRUNCATE_START 0x00000010 /* Truncate from beginning */ #define FUZZ_TRUNCATE_END 0x00000020 /* Truncate from end */ -#define FUZZ_MAX FUZZ_TRUNCATE_END +#define FUZZ_BASE64 0x00000040 /* Try all base64 chars */ +#define FUZZ_MAX FUZZ_BASE64 /* Start fuzzing a blob of data with selected strategies (bitmask) */ struct fuzz *fuzz_begin(u_int strategies, void *p, size_t l);