Git fork

Merge branch 'es/oss-fuzz'

Backport oss-fuzz tests for us to our codebase.

* es/oss-fuzz:
fuzz: port fuzz-url-decode-mem from OSS-Fuzz
fuzz: port fuzz-parse-attr-line from OSS-Fuzz
fuzz: port fuzz-credential-from-url-gently from OSS-Fuzz

+177 -39
+3
Makefile
··· 2422 2422 FUZZ_OBJS += oss-fuzz/dummy-cmd-main.o 2423 2423 FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o 2424 2424 FUZZ_OBJS += oss-fuzz/fuzz-config.o 2425 + FUZZ_OBJS += oss-fuzz/fuzz-credential-from-url-gently.o 2425 2426 FUZZ_OBJS += oss-fuzz/fuzz-date.o 2426 2427 FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o 2427 2428 FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o 2429 + FUZZ_OBJS += oss-fuzz/fuzz-parse-attr-line.o 2430 + FUZZ_OBJS += oss-fuzz/fuzz-url-decode-mem.o 2428 2431 .PHONY: fuzz-objs 2429 2432 fuzz-objs: $(FUZZ_OBJS) 2430 2433
+2 -38
attr.c
··· 259 259 return git_attr_internal(name, strlen(name)); 260 260 } 261 261 262 - /* What does a matched pattern decide? */ 263 - struct attr_state { 264 - const struct git_attr *attr; 265 - const char *setto; 266 - }; 267 - 268 - struct pattern { 269 - const char *pattern; 270 - int patternlen; 271 - int nowildcardlen; 272 - unsigned flags; /* PATTERN_FLAG_* */ 273 - }; 274 - 275 - /* 276 - * One rule, as from a .gitattributes file. 277 - * 278 - * If is_macro is true, then u.attr is a pointer to the git_attr being 279 - * defined. 280 - * 281 - * If is_macro is false, then u.pat is the filename pattern to which the 282 - * rule applies. 283 - * 284 - * In either case, num_attr is the number of attributes affected by 285 - * this rule, and state is an array listing them. The attributes are 286 - * listed as they appear in the file (macros unexpanded). 287 - */ 288 - struct match_attr { 289 - union { 290 - struct pattern pat; 291 - const struct git_attr *attr; 292 - } u; 293 - char is_macro; 294 - size_t num_attr; 295 - struct attr_state state[FLEX_ARRAY]; 296 - }; 297 - 298 262 static const char blank[] = " \t\r\n"; 299 263 300 264 /* Flags usable in read_attr() and parse_attr_line() family of functions. */ ··· 353 317 return ep + strspn(ep, blank); 354 318 } 355 319 356 - static struct match_attr *parse_attr_line(const char *line, const char *src, 357 - int lineno, unsigned flags) 320 + struct match_attr *parse_attr_line(const char *line, const char *src, 321 + int lineno, unsigned flags) 358 322 { 359 323 size_t namelen, num_attr, i; 360 324 const char *cp, *name, *states;
+43
attr.h
··· 240 240 241 241 extern char *git_attr_tree; 242 242 243 + /* 244 + * Exposed for fuzz-testing only. 245 + */ 246 + 247 + /* What does a matched pattern decide? */ 248 + struct attr_state { 249 + const struct git_attr *attr; 250 + const char *setto; 251 + }; 252 + 253 + struct pattern { 254 + const char *pattern; 255 + int patternlen; 256 + int nowildcardlen; 257 + unsigned flags; /* PATTERN_FLAG_* */ 258 + }; 259 + 260 + /* 261 + * One rule, as from a .gitattributes file. 262 + * 263 + * If is_macro is true, then u.attr is a pointer to the git_attr being 264 + * defined. 265 + * 266 + * If is_macro is false, then u.pat is the filename pattern to which the 267 + * rule applies. 268 + * 269 + * In either case, num_attr is the number of attributes affected by 270 + * this rule, and state is an array listing them. The attributes are 271 + * listed as they appear in the file (macros unexpanded). 272 + */ 273 + struct match_attr { 274 + union { 275 + struct pattern pat; 276 + const struct git_attr *attr; 277 + } u; 278 + char is_macro; 279 + size_t num_attr; 280 + struct attr_state state[FLEX_ARRAY]; 281 + }; 282 + 283 + struct match_attr *parse_attr_line(const char *line, const char *src, 284 + int lineno, unsigned flags); 285 + 243 286 #endif /* ATTR_H */
+12 -1
ci/run-build-and-minimal-fuzzers.sh
··· 13 13 LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \ 14 14 fuzz-all 15 15 16 - for fuzzer in commit-graph config date pack-headers pack-idx ; do 16 + fuzzers=" 17 + commit-graph 18 + config 19 + credential-from-url-gently 20 + date 21 + pack-headers 22 + pack-idx 23 + parse-attr-line 24 + url-decode-mem 25 + " 26 + 27 + for fuzzer in $fuzzers; do 17 28 begin_group "fuzz-$fuzzer" 18 29 ./oss-fuzz/fuzz-$fuzzer -verbosity=0 -runs=1 || exit 1 19 30 end_group "fuzz-$fuzzer"
+3
oss-fuzz/.gitignore
··· 1 1 fuzz-commit-graph 2 2 fuzz-config 3 + fuzz-credential-from-url-gently 3 4 fuzz-date 4 5 fuzz-pack-headers 5 6 fuzz-pack-idx 7 + fuzz-parse-attr-line 8 + fuzz-url-decode-mem
+32
oss-fuzz/fuzz-credential-from-url-gently.c
··· 1 + #include "git-compat-util.h" 2 + #include <stddef.h> 3 + #include <stdlib.h> 4 + #include <stdint.h> 5 + #include <string.h> 6 + #include <stdio.h> 7 + #include "credential.h" 8 + 9 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); 10 + 11 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) 12 + { 13 + struct credential c; 14 + char *buf; 15 + 16 + buf = malloc(size + 1); 17 + if (!buf) 18 + return 0; 19 + 20 + memcpy(buf, data, size); 21 + buf[size] = 0; 22 + 23 + // start fuzzing 24 + credential_init(&c); 25 + credential_from_url_gently(&c, buf, 1); 26 + 27 + // cleanup 28 + credential_clear(&c); 29 + free(buf); 30 + 31 + return 0; 32 + }
+39
oss-fuzz/fuzz-parse-attr-line.c
··· 1 + #include "git-compat-util.h" 2 + #include <stddef.h> 3 + #include <stdlib.h> 4 + #include <stdint.h> 5 + #include <string.h> 6 + #include "attr.h" 7 + 8 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); 9 + 10 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) 11 + { 12 + struct match_attr *res; 13 + char *buf; 14 + 15 + buf = malloc(size + 1); 16 + if (!buf) 17 + return 0; 18 + 19 + memcpy(buf, data, size); 20 + buf[size] = 0; 21 + 22 + res = parse_attr_line(buf, "dummy", 0, 0); 23 + 24 + if (res) { 25 + int j; 26 + for (j = 0; j < res->num_attr; j++) { 27 + const char *setto = res->state[j].setto; 28 + if (ATTR_TRUE(setto) || ATTR_FALSE(setto) || 29 + ATTR_UNSET(setto)) 30 + ; 31 + else 32 + free((char *)setto); 33 + } 34 + free(res); 35 + } 36 + free(buf); 37 + 38 + return 0; 39 + }
+43
oss-fuzz/fuzz-url-decode-mem.c
··· 1 + #include "git-compat-util.h" 2 + #include <stddef.h> 3 + #include <stdlib.h> 4 + #include <stdint.h> 5 + #include <string.h> 6 + #include <stdio.h> 7 + #include "url.h" 8 + 9 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); 10 + 11 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) 12 + { 13 + char *buf; 14 + char *r; 15 + const char *pbuf; 16 + 17 + buf = malloc(size + 1); 18 + if (!buf) 19 + return 0; 20 + 21 + memcpy(buf, data, size); 22 + buf[size] = 0; 23 + 24 + // start fuzzing 25 + r = url_decode(buf); 26 + free(r); 27 + 28 + r = url_percent_decode(buf); 29 + free(r); 30 + 31 + pbuf = (const char*) buf; 32 + r = url_decode_parameter_name(&pbuf); 33 + free(r); 34 + 35 + pbuf = (const char*) buf; 36 + r = url_decode_parameter_value(&pbuf); 37 + free(r); 38 + 39 + // cleanup 40 + free(buf); 41 + 42 + return 0; 43 + }