diff --git a/Makefile b/Makefile index 5776309365..94ceadb6cb 100644 --- a/Makefile +++ b/Makefile @@ -750,6 +750,7 @@ SCRIPTS = $(SCRIPT_SH_GEN) \ ETAGS_TARGET = TAGS FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o +FUZZ_OBJS += oss-fuzz/fuzz-date.o FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o .PHONY: fuzz-objs diff --git a/oss-fuzz/.gitignore b/oss-fuzz/.gitignore index 9acb74412e..5b95408825 100644 --- a/oss-fuzz/.gitignore +++ b/oss-fuzz/.gitignore @@ -1,3 +1,4 @@ fuzz-commit-graph +fuzz-date fuzz-pack-headers fuzz-pack-idx diff --git a/oss-fuzz/fuzz-date.c b/oss-fuzz/fuzz-date.c new file mode 100644 index 0000000000..036378b946 --- /dev/null +++ b/oss-fuzz/fuzz-date.c @@ -0,0 +1,49 @@ +#include "git-compat-util.h" +#include "date.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + int local; + int num; + char *str; + int16_t tz; + timestamp_t ts; + enum date_mode_type dmtype; + struct date_mode *dm; + + if (size <= 4) + /* + * we use the first byte to fuzz dmtype and the + * second byte to fuzz local, then the next two + * bytes to fuzz tz offset. The remainder + * (at least one byte) is fed as input to + * approxidate_careful(). + */ + return 0; + + local = !!(*data++ & 0x10); + num = *data++ % DATE_UNIX; + if (num >= DATE_STRFTIME) + num++; + dmtype = (enum date_mode_type)num; + size -= 2; + + tz = *data++; + tz = (tz << 8) | *data++; + size -= 2; + + str = xmemdupz(data, size); + + ts = approxidate_careful(str, &num); + free(str); + + dm = date_mode_from_type(dmtype); + dm->local = local; + show_date(ts, (int)tz, dm); + + date_mode_release(dm); + + return 0; +}