mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 11:06:32 +00:00
There are several places where users may want to specify the type of object IDs (sha1 or sha256) that should be used, for example, when dealing with repositories, indexes, etc. However, given that sha256 support remains disappointingly uncommon in the wild, we should avoid hard API breaks when possible. Instead, update these APIs to have an "extended" format (eg, `git_odb_open_ext`) that provides an options structure with oid type information. This allows callers who do care about sha256 to use it, and callers who do not to avoid gratuitous API breakage.
137 lines
3.1 KiB
C
137 lines
3.1 KiB
C
/*
|
|
* libgit2 packfile fuzzer target.
|
|
*
|
|
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
*
|
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "git2.h"
|
|
#include "git2/sys/mempack.h"
|
|
#include "common.h"
|
|
#include "str.h"
|
|
|
|
#include "standalone_driver.h"
|
|
|
|
static git_odb *odb = NULL;
|
|
static git_odb_backend *mempack = NULL;
|
|
|
|
/* Arbitrary object to seed the ODB. */
|
|
static const unsigned char base_obj[] = { 07, 076 };
|
|
static const unsigned int base_obj_len = 2;
|
|
|
|
int LLVMFuzzerInitialize(int *argc, char ***argv)
|
|
{
|
|
GIT_UNUSED(argc);
|
|
GIT_UNUSED(argv);
|
|
|
|
if (git_libgit2_init() < 0) {
|
|
fprintf(stderr, "Failed to initialize libgit2\n");
|
|
abort();
|
|
}
|
|
if (git_libgit2_opts(GIT_OPT_SET_PACK_MAX_OBJECTS, 10000000) < 0) {
|
|
fprintf(stderr, "Failed to limit maximum pack object count\n");
|
|
abort();
|
|
}
|
|
|
|
if (git_odb_new(&odb) < 0) {
|
|
fprintf(stderr, "Failed to create the odb\n");
|
|
abort();
|
|
}
|
|
|
|
if (git_mempack_new(&mempack) < 0) {
|
|
fprintf(stderr, "Failed to create the mempack\n");
|
|
abort();
|
|
}
|
|
if (git_odb_add_backend(odb, mempack, 999) < 0) {
|
|
fprintf(stderr, "Failed to add the mempack\n");
|
|
abort();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
|
{
|
|
git_indexer_progress stats = {0, 0};
|
|
git_indexer *indexer = NULL;
|
|
git_str path = GIT_STR_INIT;
|
|
git_oid oid;
|
|
bool append_hash = false;
|
|
int error;
|
|
|
|
if (size == 0)
|
|
return 0;
|
|
|
|
if (!odb || !mempack) {
|
|
fprintf(stderr, "Global state not initialized\n");
|
|
abort();
|
|
}
|
|
git_mempack_reset(mempack);
|
|
|
|
if (git_odb_write(&oid, odb, base_obj, base_obj_len, GIT_OBJECT_BLOB) < 0) {
|
|
fprintf(stderr, "Failed to add an object to the odb\n");
|
|
abort();
|
|
}
|
|
|
|
#ifdef GIT_EXPERIMENTAL_SHA256
|
|
error = git_indexer_new(&indexer, ".", NULL);
|
|
#else
|
|
error = git_indexer_new(&indexer, ".", 0, odb, NULL);
|
|
#endif
|
|
|
|
if (error < 0) {
|
|
fprintf(stderr, "Failed to create the indexer: %s\n",
|
|
git_error_last()->message);
|
|
abort();
|
|
}
|
|
|
|
/*
|
|
* If the first byte in the stream has the high bit set, append the
|
|
* SHA1 hash so that the packfile is somewhat valid.
|
|
*/
|
|
append_hash = *data & 0x80;
|
|
++data;
|
|
--size;
|
|
|
|
if (git_indexer_append(indexer, data, size, &stats) < 0)
|
|
goto cleanup;
|
|
if (append_hash) {
|
|
#ifdef GIT_EXPERIMENTAL_SHA256
|
|
if (git_odb_hash(&oid, data, size, GIT_OBJECT_BLOB, GIT_OID_SHA1) < 0) {
|
|
fprintf(stderr, "Failed to compute the SHA1 hash\n");
|
|
abort();
|
|
}
|
|
#else
|
|
if (git_odb_hash(&oid, data, size, GIT_OBJECT_BLOB) < 0) {
|
|
fprintf(stderr, "Failed to compute the SHA1 hash\n");
|
|
abort();
|
|
}
|
|
#endif
|
|
|
|
if (git_indexer_append(indexer, &oid.id, GIT_OID_SHA1_SIZE, &stats) < 0) {
|
|
goto cleanup;
|
|
}
|
|
}
|
|
if (git_indexer_commit(indexer, &stats) < 0)
|
|
goto cleanup;
|
|
|
|
if (git_str_printf(&path, "pack-%s.idx", git_indexer_name(indexer)) < 0)
|
|
goto cleanup;
|
|
p_unlink(git_str_cstr(&path));
|
|
|
|
git_str_clear(&path);
|
|
|
|
if (git_str_printf(&path, "pack-%s.pack", git_indexer_name(indexer)) < 0)
|
|
goto cleanup;
|
|
p_unlink(git_str_cstr(&path));
|
|
|
|
cleanup:
|
|
git_mempack_reset(mempack);
|
|
git_indexer_free(indexer);
|
|
git_str_dispose(&path);
|
|
return 0;
|
|
}
|