From: Arthur Chan <arthur.chan@xxxxxxxxxxxxx> Signed-off-by: Arthur Chan <arthur.chan@xxxxxxxxxxxxx> --- fuzz: add new oss-fuzz fuzzer for date.c / date.h This patch is aimed to add a new oss-fuzz fuzzer to the oss-fuzz directory for fuzzing date.c / date.h in the base directory. The .gitignore of the oss-fuzz directory and the Makefile have been modified to accommodate the new fuzzer fuzz-date.c. Fixed the objects order in .gitignore and Makefiles and fixed some of the logic and formatting for the fuzz-date.c fuzzer in v2. Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1612%2Farthurscchan%2Fnew-fuzzer-date-v2 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1612/arthurscchan/new-fuzzer-date-v2 Pull-Request: https://github.com/gitgitgadget/git/pull/1612 Range-diff vs v1: 1: d43724c19d0 ! 1: 2928e2b858d fuzz: add new oss-fuzz fuzzer for date.c / date.h @@ Commit message Signed-off-by: Arthur Chan <arthur.chan@xxxxxxxxxxxxx> ## Makefile ## -@@ Makefile: ETAGS_TARGET = TAGS +@@ Makefile: 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 -+FUZZ_OBJS += oss-fuzz/fuzz-date.o .PHONY: fuzz-objs - fuzz-objs: $(FUZZ_OBJS) - ## oss-fuzz/.gitignore ## @@ fuzz-commit-graph ++fuzz-date fuzz-pack-headers fuzz-pack-idx -+fuzz-date ## oss-fuzz/fuzz-date.c (new) ## @@ @@ oss-fuzz/fuzz-date.c (new) + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ -+ int type; -+ int time; ++ int local; + int num; ++ uint16_t tz; + char *str; + timestamp_t ts; + enum date_mode_type dmtype; + struct date_mode *dm; + -+ if (size <= 8) -+ { ++ if (size <= 4) ++ /* ++ * we use the first byte to fuzz dmtype and local, ++ * then the next three bytes to fuzz tz offset, ++ * and the remainder (at least one byte) is fed ++ * as end-user input to approxidate_careful(). ++ */ + return 0; -+ } + -+ type = (*((int *)data)) % 8; -+ data += 4; -+ size -= 4; ++ local = !!(*data & 0x10); ++ dmtype = (enum date_mode_type)(*data % DATE_UNIX); ++ if (dmtype == DATE_STRFTIME) ++ /* ++ * Currently DATE_STRFTIME is not supported. ++ */ ++ return 0; ++ data++; ++ size--; + -+ time = abs(*((int *)data)); -+ data += 4; -+ size -= 4; ++ tz = *data++; ++ tz = (tz << 8) | *data++; ++ tz = (tz << 8) | *data++; ++ size -= 3; + -+ str = (char *)malloc(size+1); ++ str = (char *)malloc(size + 1); + if (!str) -+ { + return 0; -+ } + memcpy(str, data, size); + str[size] = '\0'; + + ts = approxidate_careful(str, &num); + free(str); + -+ switch(type) -+ { -+ case 0: default: -+ dmtype = DATE_NORMAL; -+ break; -+ case 1: -+ dmtype = DATE_HUMAN; -+ break; -+ case 2: -+ dmtype = DATE_SHORT; -+ break; -+ case 3: -+ dmtype = DATE_ISO8601; -+ break; -+ case 4: -+ dmtype = DATE_ISO8601_STRICT; -+ break; -+ case 5: -+ dmtype = DATE_RFC2822; -+ break; -+ case 6: -+ dmtype = DATE_RAW; -+ break; -+ case 7: -+ dmtype = DATE_UNIX; -+ break; -+ } -+ + dm = date_mode_from_type(dmtype); -+ dm->local = 1; -+ show_date(ts, time, dm); ++ dm->local = local; ++ show_date(ts, (int16_t)tz, dm); + + date_mode_release(dm); + Makefile | 1 + oss-fuzz/.gitignore | 1 + oss-fuzz/fuzz-date.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 oss-fuzz/fuzz-date.c diff --git a/Makefile b/Makefile index 03adcb5a480..4b875ef6ce1 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 9acb74412ef..5b954088254 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 00000000000..a5c887bf11c --- /dev/null +++ b/oss-fuzz/fuzz-date.c @@ -0,0 +1,56 @@ +#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; + uint16_t tz; + char *str; + timestamp_t ts; + enum date_mode_type dmtype; + struct date_mode *dm; + + if (size <= 4) + /* + * we use the first byte to fuzz dmtype and local, + * then the next three bytes to fuzz tz offset, + * and the remainder (at least one byte) is fed + * as end-user input to approxidate_careful(). + */ + return 0; + + local = !!(*data & 0x10); + dmtype = (enum date_mode_type)(*data % DATE_UNIX); + if (dmtype == DATE_STRFTIME) + /* + * Currently DATE_STRFTIME is not supported. + */ + return 0; + data++; + size--; + + tz = *data++; + tz = (tz << 8) | *data++; + tz = (tz << 8) | *data++; + size -= 3; + + str = (char *)malloc(size + 1); + if (!str) + return 0; + memcpy(str, data, size); + str[size] = '\0'; + + ts = approxidate_careful(str, &num); + free(str); + + dm = date_mode_from_type(dmtype); + dm->local = local; + show_date(ts, (int16_t)tz, dm); + + date_mode_release(dm); + + return 0; +} base-commit: dadef801b365989099a9929e995589e455c51fed -- gitgitgadget