]> git.proxmox.com Git - libgit2.git/blob - fuzzers/packfile_fuzzer.c
50c11575524f81c7add893c314e66ad733adc689
[libgit2.git] / fuzzers / packfile_fuzzer.c
1 /*
2 * libgit2 packfile fuzzer target.
3 *
4 * Copyright (C) the libgit2 contributors. All rights reserved.
5 *
6 * This file is part of libgit2, distributed under the GNU GPL v2 with
7 * a Linking Exception. For full terms see the included COPYING file.
8 */
9
10 #include <stdio.h>
11
12 #include "git2.h"
13 #include "git2/sys/mempack.h"
14 #include "common.h"
15 #include "buffer.h"
16
17 static git_odb *odb = NULL;
18 static git_odb_backend *mempack = NULL;
19
20 /* Arbitrary object to seed the ODB. */
21 static const unsigned char base_obj[] = { 07, 076 };
22 static const unsigned int base_obj_len = 2;
23
24 int LLVMFuzzerInitialize(int *argc, char ***argv)
25 {
26 GIT_UNUSED(argc);
27 GIT_UNUSED(argv);
28
29 if (git_libgit2_init() < 0) {
30 fprintf(stderr, "Failed to initialize libgit2\n");
31 abort();
32 }
33 if (git_libgit2_opts(GIT_OPT_SET_PACK_MAX_OBJECTS, 10000000) < 0) {
34 fprintf(stderr, "Failed to limit maximum pack object count\n");
35 abort();
36 }
37 if (git_odb_new(&odb) < 0) {
38 fprintf(stderr, "Failed to create the odb\n");
39 abort();
40 }
41 if (git_mempack_new(&mempack) < 0) {
42 fprintf(stderr, "Failed to create the mempack\n");
43 abort();
44 }
45 if (git_odb_add_backend(odb, mempack, 999) < 0) {
46 fprintf(stderr, "Failed to add the mempack\n");
47 abort();
48 }
49 return 0;
50 }
51
52 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
53 {
54 git_indexer_progress stats = {0, 0};
55 git_indexer *indexer = NULL;
56 git_buf path = GIT_BUF_INIT;
57 git_oid oid;
58 bool append_hash = false;
59
60 if (size == 0)
61 return 0;
62
63 if (!odb || !mempack) {
64 fprintf(stderr, "Global state not initialized\n");
65 abort();
66 }
67 git_mempack_reset(mempack);
68
69 if (git_odb_write(&oid, odb, base_obj, base_obj_len, GIT_OBJECT_BLOB) < 0) {
70 fprintf(stderr, "Failed to add an object to the odb\n");
71 abort();
72 }
73
74 if (git_indexer_new(&indexer, ".", 0, odb, NULL) < 0) {
75 fprintf(stderr, "Failed to create the indexer: %s\n",
76 git_error_last()->message);
77 abort();
78 }
79
80 /*
81 * If the first byte in the stream has the high bit set, append the
82 * SHA1 hash so that the packfile is somewhat valid.
83 */
84 append_hash = *data & 0x80;
85 ++data;
86 --size;
87
88 if (git_indexer_append(indexer, data, size, &stats) < 0)
89 goto cleanup;
90 if (append_hash) {
91 if (git_odb_hash(&oid, data, size, GIT_OBJECT_BLOB) < 0) {
92 fprintf(stderr, "Failed to compute the SHA1 hash\n");
93 abort();
94 }
95 if (git_indexer_append(indexer, &oid, sizeof(oid), &stats) < 0) {
96 goto cleanup;
97 }
98 }
99 if (git_indexer_commit(indexer, &stats) < 0)
100 goto cleanup;
101
102 if (git_buf_printf(&path, "pack-%s.idx", git_oid_tostr_s(git_indexer_hash(indexer))) < 0)
103 goto cleanup;
104 p_unlink(git_buf_cstr(&path));
105
106 git_buf_clear(&path);
107
108 if (git_buf_printf(&path, "pack-%s.pack", git_oid_tostr_s(git_indexer_hash(indexer))) < 0)
109 goto cleanup;
110 p_unlink(git_buf_cstr(&path));
111
112 cleanup:
113 git_mempack_reset(mempack);
114 git_indexer_free(indexer);
115 git_buf_dispose(&path);
116 return 0;
117 }