2 * libgit2 raw packfile fuzz target.
4 * Copyright (C) the libgit2 contributors. All rights reserved.
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.
15 #include "git2/sys/transport.h"
18 #include "standalone_driver.h"
20 #define UNUSED(x) (void)(x)
22 struct fuzzer_buffer
{
23 const unsigned char *data
;
27 struct fuzzer_stream
{
28 git_smart_subtransport_stream base
;
29 const unsigned char *readp
;
30 const unsigned char *endp
;
33 struct fuzzer_subtransport
{
34 git_smart_subtransport base
;
36 struct fuzzer_buffer data
;
39 static git_repository
*repo
;
41 static int fuzzer_stream_read(git_smart_subtransport_stream
*stream
,
46 struct fuzzer_stream
*fs
= (struct fuzzer_stream
*) stream
;
47 size_t avail
= fs
->endp
- fs
->readp
;
49 *bytes_read
= (buf_size
> avail
) ? avail
: buf_size
;
50 memcpy(buffer
, fs
->readp
, *bytes_read
);
51 fs
->readp
+= *bytes_read
;
56 static int fuzzer_stream_write(git_smart_subtransport_stream
*stream
,
57 const char *buffer
, size_t len
)
65 static void fuzzer_stream_free(git_smart_subtransport_stream
*stream
)
70 static int fuzzer_stream_new(
71 struct fuzzer_stream
**out
,
72 const struct fuzzer_buffer
*data
)
74 struct fuzzer_stream
*stream
= malloc(sizeof(*stream
));
78 stream
->readp
= data
->data
;
79 stream
->endp
= data
->data
+ data
->size
;
80 stream
->base
.read
= fuzzer_stream_read
;
81 stream
->base
.write
= fuzzer_stream_write
;
82 stream
->base
.free
= fuzzer_stream_free
;
89 static int fuzzer_subtransport_action(
90 git_smart_subtransport_stream
**out
,
91 git_smart_subtransport
*transport
,
93 git_smart_service_t action
)
95 struct fuzzer_subtransport
*ft
= (struct fuzzer_subtransport
*) transport
;
100 return fuzzer_stream_new((struct fuzzer_stream
**) out
, &ft
->data
);
103 static int fuzzer_subtransport_close(git_smart_subtransport
*transport
)
109 static void fuzzer_subtransport_free(git_smart_subtransport
*transport
)
114 static int fuzzer_subtransport_new(
115 struct fuzzer_subtransport
**out
,
116 git_transport
*owner
,
117 const struct fuzzer_buffer
*data
)
119 struct fuzzer_subtransport
*sub
= malloc(sizeof(*sub
));
124 sub
->data
.data
= data
->data
;
125 sub
->data
.size
= data
->size
;
126 sub
->base
.action
= fuzzer_subtransport_action
;
127 sub
->base
.close
= fuzzer_subtransport_close
;
128 sub
->base
.free
= fuzzer_subtransport_free
;
135 static int fuzzer_subtransport_cb(
136 git_smart_subtransport
**out
,
137 git_transport
*owner
,
140 struct fuzzer_buffer
*buf
= (struct fuzzer_buffer
*) payload
;
141 struct fuzzer_subtransport
*sub
;
143 if (fuzzer_subtransport_new(&sub
, owner
, buf
) < 0)
150 static int fuzzer_transport_cb(git_transport
**out
, git_remote
*owner
, void *param
)
152 git_smart_subtransport_definition def
= {
153 fuzzer_subtransport_cb
,
157 return git_transport_smart(out
, owner
, &def
);
160 static void fuzzer_git_abort(const char *op
)
162 const git_error
*err
= git_error_last();
163 fprintf(stderr
, "unexpected libgit error: %s: %s\n",
164 op
, err
? err
->message
: "<none>");
168 int LLVMFuzzerInitialize(int *argc
, char ***argv
)
171 char tmpdir
[MAX_PATH
], path
[MAX_PATH
];
173 if (GetTempPath((DWORD
)sizeof(tmpdir
), tmpdir
) == 0)
176 if (GetTempFileName(tmpdir
, "lg2", 1, path
) == 0)
179 if (git_futils_mkdir(path
, 0700, 0) < 0)
182 char path
[] = "/tmp/git2.XXXXXX";
184 if (mkdtemp(path
) != path
)
188 if (git_libgit2_init() < 0)
191 if (git_libgit2_opts(GIT_OPT_SET_PACK_MAX_OBJECTS
, 10000000) < 0)
197 if (git_repository_init(&repo
, path
, 1) < 0)
198 fuzzer_git_abort("git_repository_init");
203 int LLVMFuzzerTestOneInput(const unsigned char *data
, size_t size
)
205 struct fuzzer_buffer buffer
= { data
, size
};
206 git_remote_callbacks callbacks
= GIT_REMOTE_CALLBACKS_INIT
;
209 if (git_remote_create_anonymous(&remote
, repo
, "fuzzer://remote-url") < 0)
210 fuzzer_git_abort("git_remote_create");
212 callbacks
.transport
= fuzzer_transport_cb
;
213 callbacks
.payload
= &buffer
;
215 if (git_remote_connect(remote
, GIT_DIRECTION_FETCH
,
216 &callbacks
, NULL
, NULL
) < 0)
219 git_remote_download(remote
, NULL
, NULL
);
222 git_remote_free(remote
);