summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2022-09-21 05:09:46 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2023-02-12 22:02:00 +0000
commitfe2ee3a018286b04cd0c64f84d437c7317c8f138 (patch)
tree196a29fc72ef0a27e0277b4d142cc93c28fa4cb7
parent6204499242101d0f93cd7e56e259c900828e41e1 (diff)
downloadlibgit2-fe2ee3a018286b04cd0c64f84d437c7317c8f138.tar.gz
object: lookup sha256 objects
This is much of the plumbing for the object database to support SHA256, and for objects to be able to parse SHA256 versions of themselves.
-rw-r--r--examples/index-pack.c9
-rw-r--r--fuzzers/objects_fuzzer.c2
-rw-r--r--fuzzers/packfile_fuzzer.c9
-rw-r--r--include/git2/indexer.h29
-rw-r--r--include/git2/object.h30
-rw-r--r--src/cli/cmd_hash_object.c32
-rw-r--r--src/libgit2/blob.c6
-rw-r--r--src/libgit2/blob.h4
-rw-r--r--src/libgit2/commit.c57
-rw-r--r--src/libgit2/commit.h32
-rw-r--r--src/libgit2/commit_list.c6
-rw-r--r--src/libgit2/indexer.c79
-rw-r--r--src/libgit2/object.c45
-rw-r--r--src/libgit2/object.h3
-rw-r--r--src/libgit2/odb_pack.c18
-rw-r--r--src/libgit2/pack-objects.c13
-rw-r--r--src/libgit2/repository.c5
-rw-r--r--src/libgit2/tag.c25
-rw-r--r--src/libgit2/tag.h4
-rw-r--r--src/libgit2/tree.c38
-rw-r--r--src/libgit2/tree.h4
-rw-r--r--tests/libgit2/commit/parse.c2
-rw-r--r--tests/libgit2/object/commit/parse.c298
-rw-r--r--tests/libgit2/object/lookup256.c153
-rw-r--r--tests/libgit2/object/tag/parse.c4
-rw-r--r--tests/libgit2/object/tree/parse.c4
-rw-r--r--tests/libgit2/object/validate.c154
-rw-r--r--tests/libgit2/pack/indexer.c53
-rw-r--r--tests/libgit2/pack/packbuilder.c17
29 files changed, 961 insertions, 174 deletions
diff --git a/examples/index-pack.c b/examples/index-pack.c
index df37dd0c4..0f8234c75 100644
--- a/examples/index-pack.c
+++ b/examples/index-pack.c
@@ -28,11 +28,18 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv)
return EXIT_FAILURE;
}
- if (git_indexer_new(&idx, ".", 0, NULL, NULL) < 0) {
+#ifdef GIT_EXPERIMENTAL_SHA256
+ error = git_indexer_new(&idx, ".", git_repository_oid_type(repo), NULL);
+#else
+ error = git_indexer_new(&idx, ".", 0, NULL, NULL);
+#endif
+
+ if (error < 0) {
puts("bad idx");
return -1;
}
+
if ((fd = open(argv[1], 0)) < 0) {
perror("open");
return -1;
diff --git a/fuzzers/objects_fuzzer.c b/fuzzers/objects_fuzzer.c
index 51b4a1ed4..7294e9b35 100644
--- a/fuzzers/objects_fuzzer.c
+++ b/fuzzers/objects_fuzzer.c
@@ -39,7 +39,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
* to do.
*/
for (i = 0; i < ARRAY_SIZE(types); i++) {
- if (git_object__from_raw(&object, (const char *) data, size, types[i]) < 0)
+ if (git_object__from_raw(&object, (const char *) data, size, types[i], GIT_OID_SHA1) < 0)
continue;
git_object_free(object);
object = NULL;
diff --git a/fuzzers/packfile_fuzzer.c b/fuzzers/packfile_fuzzer.c
index 52a813760..aeba9575c 100644
--- a/fuzzers/packfile_fuzzer.c
+++ b/fuzzers/packfile_fuzzer.c
@@ -67,6 +67,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
git_str path = GIT_STR_INIT;
git_oid oid;
bool append_hash = false;
+ int error;
if (size == 0)
return 0;
@@ -82,7 +83,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
abort();
}
- if (git_indexer_new(&indexer, ".", 0, odb, NULL) < 0) {
+#ifdef GIT_EXPERIMENTAL_SHA256
+ error = git_indexer_new(&indexer, ".", GIT_OID_SHA1, 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();
diff --git a/include/git2/indexer.h b/include/git2/indexer.h
index ffe9bf366..630eef934 100644
--- a/include/git2/indexer.h
+++ b/include/git2/indexer.h
@@ -62,6 +62,19 @@ typedef int GIT_CALLBACK(git_indexer_progress_cb)(const git_indexer_progress *st
typedef struct git_indexer_options {
unsigned int version;
+#ifdef GIT_EXPERIMENTAL_SHA256
+ /** permissions to use creating packfile or 0 for defaults */
+ unsigned int mode;
+
+ /**
+ * object database from which to read base objects when
+ * fixing thin packs. This can be NULL if there are no thin
+ * packs; if a thin pack is encountered, an error will be
+ * returned if there are bases missing.
+ */
+ git_odb *odb;
+#endif
+
/** progress_cb function to call with progress information */
git_indexer_progress_cb progress_cb;
@@ -87,6 +100,21 @@ GIT_EXTERN(int) git_indexer_options_init(
git_indexer_options *opts,
unsigned int version);
+#ifdef GIT_EXPERIMENTAL_SHA256
+/**
+ * Create a new indexer instance
+ *
+ * @param out where to store the indexer instance
+ * @param path to the directory where the packfile should be stored
+ * @param oid_type the oid type to use for objects
+ * @return 0 or an error code.
+ */
+GIT_EXTERN(int) git_indexer_new(
+ git_indexer **out,
+ const char *path,
+ git_oid_t oid_type,
+ git_indexer_options *opts);
+#else
/**
* Create a new indexer instance
*
@@ -106,6 +134,7 @@ GIT_EXTERN(int) git_indexer_new(
unsigned int mode,
git_odb *odb,
git_indexer_options *opts);
+#endif
/**
* Add data to the indexer
diff --git a/include/git2/object.h b/include/git2/object.h
index 5610a476f..6384aaa6e 100644
--- a/include/git2/object.h
+++ b/include/git2/object.h
@@ -225,6 +225,7 @@ GIT_EXTERN(int) git_object_peel(
*/
GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
+#ifdef GIT_EXPERIMENTAL_SHA256
/**
* Analyzes a buffer of raw object content and determines its validity.
* Tree, commit, and tag objects will be parsed and ensured that they
@@ -238,14 +239,39 @@ GIT_EXTERN(int) git_object_dup(git_object **dest, git_object *source);
* @param valid Output pointer to set with validity of the object content
* @param buf The contents to validate
* @param len The length of the buffer
- * @param type The type of the object in the buffer
+ * @param object_type The type of the object in the buffer
+ * @param oid_type The object ID type for the OIDs in the given buffer
* @return 0 on success or an error code
*/
GIT_EXTERN(int) git_object_rawcontent_is_valid(
int *valid,
const char *buf,
size_t len,
- git_object_t type);
+ git_object_t object_type,
+ git_oid_t oid_type);
+#else
+/**
+ * Analyzes a buffer of raw object content and determines its validity.
+ * Tree, commit, and tag objects will be parsed and ensured that they
+ * are valid, parseable content. (Blobs are always valid by definition.)
+ * An error message will be set with an informative message if the object
+ * is not valid.
+ *
+ * @warning This function is experimental and its signature may change in
+ * the future.
+ *
+ * @param valid Output pointer to set with validity of the object content
+ * @param buf The contents to validate
+ * @param len The length of the buffer
+ * @param object_type The type of the object in the buffer
+ * @return 0 on success or an error code
+ */
+GIT_EXTERN(int) git_object_rawcontent_is_valid(
+ int *valid,
+ const char *buf,
+ size_t len,
+ git_object_t object_type);
+#endif
/** @} */
GIT_END_DECL
diff --git a/src/cli/cmd_hash_object.c b/src/cli/cmd_hash_object.c
index a64db8823..93b980d66 100644
--- a/src/cli/cmd_hash_object.c
+++ b/src/cli/cmd_hash_object.c
@@ -49,26 +49,37 @@ static void print_help(void)
cli_opt_help_fprint(stdout, opts);
}
-static int hash_buf(git_odb *odb, git_str *buf, git_object_t type)
+static int hash_buf(
+ git_odb *odb,
+ git_str *buf,
+ git_object_t object_type,
+ git_oid_t oid_type)
{
git_oid oid;
if (!literally) {
int valid = 0;
- if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, type) < 0 || !valid)
+#ifdef GIT_EXPERIMENTAL_SHA256
+ if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, object_type, oid_type) < 0 || !valid)
+ return cli_error_git();
+#else
+ GIT_UNUSED(oid_type);
+
+ if (git_object_rawcontent_is_valid(&valid, buf->ptr, buf->size, object_type) < 0 || !valid)
return cli_error_git();
+#endif
}
if (write_object) {
- if (git_odb_write(&oid, odb, buf->ptr, buf->size, type) < 0)
+ if (git_odb_write(&oid, odb, buf->ptr, buf->size, object_type) < 0)
return cli_error_git();
} else {
#ifdef GIT_EXPERIMENTAL_SHA256
- if (git_odb_hash(&oid, buf->ptr, buf->size, type, GIT_OID_SHA1) < 0)
+ if (git_odb_hash(&oid, buf->ptr, buf->size, object_type, GIT_OID_SHA1) < 0)
return cli_error_git();
#else
- if (git_odb_hash(&oid, buf->ptr, buf->size, type) < 0)
+ if (git_odb_hash(&oid, buf->ptr, buf->size, object_type) < 0)
return cli_error_git();
#endif
}
@@ -83,9 +94,10 @@ int cmd_hash_object(int argc, char **argv)
{
git_repository *repo = NULL;
git_odb *odb = NULL;
+ git_oid_t oid_type;
git_str buf = GIT_STR_INIT;
cli_opt invalid_opt;
- git_object_t type = GIT_OBJECT_BLOB;
+ git_object_t object_type = GIT_OBJECT_BLOB;
char **filename;
int ret = 0;
@@ -97,7 +109,7 @@ int cmd_hash_object(int argc, char **argv)
return 0;
}
- if (type_name && (type = git_object_string2type(type_name)) == GIT_OBJECT_INVALID)
+ if (type_name && (object_type = git_object_string2type(type_name)) == GIT_OBJECT_INVALID)
return cli_error_usage("invalid object type '%s'", type_name);
if (write_object &&
@@ -107,6 +119,8 @@ int cmd_hash_object(int argc, char **argv)
goto done;
}
+ oid_type = git_repository_oid_type(repo);
+
/*
* TODO: we're reading blobs, we shouldn't pull them all into main
* memory, we should just stream them into the odb instead.
@@ -118,7 +132,7 @@ int cmd_hash_object(int argc, char **argv)
goto done;
}
- if ((ret = hash_buf(odb, &buf, type)) != 0)
+ if ((ret = hash_buf(odb, &buf, object_type, oid_type)) != 0)
goto done;
} else {
for (filename = filenames; *filename; filename++) {
@@ -127,7 +141,7 @@ int cmd_hash_object(int argc, char **argv)
goto done;
}
- if ((ret = hash_buf(odb, &buf, type)) != 0)
+ if ((ret = hash_buf(odb, &buf, object_type, oid_type)) != 0)
goto done;
}
}
diff --git a/src/libgit2/blob.c b/src/libgit2/blob.c
index b1680d3a8..5cfd7474b 100644
--- a/src/libgit2/blob.c
+++ b/src/libgit2/blob.c
@@ -52,11 +52,12 @@ void git_blob__free(void *_blob)
git__free(blob);
}
-int git_blob__parse_raw(void *_blob, const char *data, size_t size)
+int git_blob__parse_raw(void *_blob, const char *data, size_t size, git_oid_t oid_type)
{
git_blob *blob = (git_blob *) _blob;
GIT_ASSERT_ARG(blob);
+ GIT_UNUSED(oid_type);
blob->raw = 1;
blob->data.raw.data = data;
@@ -64,11 +65,12 @@ int git_blob__parse_raw(void *_blob, const char *data, size_t size)
return 0;
}
-int git_blob__parse(void *_blob, git_odb_object *odb_obj)
+int git_blob__parse(void *_blob, git_odb_object *odb_obj, git_oid_t oid_type)
{
git_blob *blob = (git_blob *) _blob;
GIT_ASSERT_ARG(blob);
+ GIT_UNUSED(oid_type);
git_cached_obj_incref((git_cached_obj *)odb_obj);
blob->raw = 0;
diff --git a/src/libgit2/blob.h b/src/libgit2/blob.h
index 9a5dda225..d6c9dd99b 100644
--- a/src/libgit2/blob.h
+++ b/src/libgit2/blob.h
@@ -36,8 +36,8 @@ struct git_blob {
} while(0)
void git_blob__free(void *blob);
-int git_blob__parse(void *blob, git_odb_object *obj);
-int git_blob__parse_raw(void *blob, const char *data, size_t size);
+int git_blob__parse(void *blob, git_odb_object *obj, git_oid_t oid_type);
+int git_blob__parse_raw(void *blob, const char *data, size_t size, git_oid_t oid_type);
int git_blob__getbuf(git_str *buffer, git_blob *blob);
extern int git_blob__create_from_paths(
diff --git a/src/libgit2/commit.c b/src/libgit2/commit.c
index 114ae6fc9..d85fefb3d 100644
--- a/src/libgit2/commit.c
+++ b/src/libgit2/commit.c
@@ -390,7 +390,11 @@ int git_commit_amend(
return error;
}
-static int commit_parse(git_commit *commit, const char *data, size_t size, unsigned int flags)
+static int commit_parse(
+ git_commit *commit,
+ const char *data,
+ size_t size,
+ git_commit__parse_options *opts)
{
const char *buffer_start = data, *buffer;
const char *buffer_end = buffer_start + size;
@@ -401,6 +405,7 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig
GIT_ASSERT_ARG(commit);
GIT_ASSERT_ARG(data);
+ GIT_ASSERT_ARG(opts);
buffer = buffer_start;
@@ -409,13 +414,14 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig
GIT_ERROR_CHECK_ARRAY(commit->parent_ids);
/* The tree is always the first field */
- if (!(flags & GIT_COMMIT_PARSE_QUICK)) {
+ if (!(opts->flags & GIT_COMMIT_PARSE_QUICK)) {
if (git_object__parse_oid_header(&commit->tree_id,
&buffer, buffer_end, "tree ",
- GIT_OID_SHA1) < 0)
+ opts->oid_type) < 0)
goto bad_buffer;
} else {
- size_t tree_len = strlen("tree ") + GIT_OID_SHA1_HEXSIZE + 1;
+ size_t tree_len = strlen("tree ") + git_oid_hexsize(opts->oid_type) + 1;
+
if (buffer + tree_len > buffer_end)
goto bad_buffer;
buffer += tree_len;
@@ -427,14 +433,14 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig
while (git_object__parse_oid_header(&parent_id,
&buffer, buffer_end, "parent ",
- GIT_OID_SHA1) == 0) {
+ opts->oid_type) == 0) {
git_oid *new_id = git_array_alloc(commit->parent_ids);
GIT_ERROR_CHECK_ALLOC(new_id);
git_oid_cpy(new_id, &parent_id);
}
- if (!(flags & GIT_COMMIT_PARSE_QUICK)) {
+ if (!opts || !(opts->flags & GIT_COMMIT_PARSE_QUICK)) {
commit->author = git__malloc(sizeof(git_signature));
GIT_ERROR_CHECK_ALLOC(commit->author);
@@ -458,7 +464,7 @@ static int commit_parse(git_commit *commit, const char *data, size_t size, unsig
if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n')) < 0)
return error;
- if (flags & GIT_COMMIT_PARSE_QUICK)
+ if (opts && opts->flags & GIT_COMMIT_PARSE_QUICK)
return 0;
/* Parse add'l header entries */
@@ -503,19 +509,39 @@ bad_buffer:
return GIT_EINVALID;
}
-int git_commit__parse_raw(void *commit, const char *data, size_t size)
+int git_commit__parse(
+ void *commit,
+ git_odb_object *odb_obj,
+ git_oid_t oid_type)
{
- return commit_parse(commit, data, size, 0);
+ git_commit__parse_options parse_options = {0};
+ parse_options.oid_type = oid_type;
+
+ return git_commit__parse_ext(commit, odb_obj, &parse_options);
}
-int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags)
+int git_commit__parse_raw(
+ void *commit,
+ const char *data,
+ size_t size,
+ git_oid_t oid_type)
{
- return commit_parse(commit, git_odb_object_data(odb_obj), git_odb_object_size(odb_obj), flags);
+ git_commit__parse_options parse_options = {0};
+ parse_options.oid_type = oid_type;
+
+ return commit_parse(commit, data, size, &parse_options);
}
-int git_commit__parse(void *_commit, git_odb_object *odb_obj)
+int git_commit__parse_ext(
+ git_commit *commit,
+ git_odb_object *odb_obj,
+ git_commit__parse_options *parse_opts)
{
- return git_commit__parse_ext(_commit, odb_obj, 0);
+ return commit_parse(
+ commit,
+ git_odb_object_data(odb_obj),
+ git_odb_object_size(odb_obj),
+ parse_opts);
}
#define GIT_COMMIT_GETTER(_rvalue, _name, _return, _invalid) \
@@ -985,11 +1011,14 @@ int git_commit_create_with_signature(
git_str commit = GIT_STR_INIT;
git_commit *parsed;
git_array_oid_t parents = GIT_ARRAY_INIT;
+ git_commit__parse_options parse_opts = {0};
+
+ parse_opts.oid_type = repo->oid_type;
/* The first step is to verify that all the tree and parents exist */
parsed = git__calloc(1, sizeof(git_commit));
GIT_ERROR_CHECK_ALLOC(parsed);
- if (commit_parse(parsed, commit_content, strlen(commit_content), 0) < 0) {
+ if (commit_parse(parsed, commit_content, strlen(commit_content), &parse_opts) < 0) {
error = -1;
goto cleanup;
}
diff --git a/src/libgit2/commit.h b/src/libgit2/commit.h
index 7a2454e61..c25fee327 100644
--- a/src/libgit2/commit.h
+++ b/src/libgit2/commit.h
@@ -33,6 +33,16 @@ struct git_commit {
char *body;
};
+typedef struct {
+ git_oid_t oid_type;
+ unsigned int flags;
+} git_commit__parse_options;
+
+typedef enum {
+ /** Only parse parents and committer info */
+ GIT_COMMIT_PARSE_QUICK = (1 << 0)
+} git_commit__parse_flags;
+
int git_commit__header_field(
git_str *out,
const git_commit *commit,
@@ -56,14 +66,22 @@ int git_commit__create_buffer(
size_t parent_count,
const git_commit *parents[]);
-void git_commit__free(void *commit);
-int git_commit__parse(void *commit, git_odb_object *obj);
-int git_commit__parse_raw(void *commit, const char *data, size_t size);
+int git_commit__parse(
+ void *commit,
+ git_odb_object *obj,
+ git_oid_t oid_type);
-typedef enum {
- GIT_COMMIT_PARSE_QUICK = (1 << 0) /**< Only parse parents and committer info */
-} git_commit__parse_flags;
+int git_commit__parse_raw(
+ void *commit,
+ const char *data,
+ size_t size,
+ git_oid_t oid_type);
-int git_commit__parse_ext(git_commit *commit, git_odb_object *odb_obj, unsigned int flags);
+int git_commit__parse_ext(
+ git_commit *commit,
+ git_odb_object *odb_obj,
+ git_commit__parse_options *parse_opts);
+
+void git_commit__free(void *commit);
#endif
diff --git a/src/libgit2/commit_list.c b/src/libgit2/commit_list.c
index 511d7291f..12b329b25 100644
--- a/src/libgit2/commit_list.c
+++ b/src/libgit2/commit_list.c
@@ -124,13 +124,17 @@ static int commit_quick_parse(
{
git_oid *parent_oid;
git_commit *commit;
+ git_commit__parse_options parse_opts = {
+ GIT_OID_SHA1,
+ GIT_COMMIT_PARSE_QUICK
+ };
size_t i;
commit = git__calloc(1, sizeof(*commit));
GIT_ERROR_CHECK_ALLOC(commit);
commit->object.repo = walk->repo;
- if (git_commit__parse_ext(commit, obj, GIT_COMMIT_PARSE_QUICK) < 0) {
+ if (git_commit__parse_ext(commit, obj, &parse_opts) < 0) {
git__free(commit);
return -1;
}
diff --git a/src/libgit2/indexer.c b/src/libgit2/indexer.c
index 98408646a..dfc326e02 100644
--- a/src/libgit2/indexer.c
+++ b/src/libgit2/indexer.c
@@ -42,6 +42,7 @@ struct git_indexer {
have_delta :1,
do_fsync :1,
do_verify :1;
+ git_oid_t oid_type;
struct git_pack_header hdr;
struct git_pack_file *pack;
unsigned int mode;
@@ -68,7 +69,7 @@ struct git_indexer {
git_odb *odb;
/* Fields for calculating the packfile trailer (hash of everything before it) */
- char inbuf[GIT_OID_SHA1_SIZE];
+ char inbuf[GIT_OID_MAX_SIZE];
size_t inbuf_len;
git_hash_ctx trailer;
};
@@ -136,12 +137,13 @@ int git_indexer_init_options(git_indexer_options *opts, unsigned int version)
}
#endif
-int git_indexer_new(
- git_indexer **out,
- const char *prefix,
- unsigned int mode,
- git_odb *odb,
- git_indexer_options *in_opts)
+static int indexer_new(
+ git_indexer **out,
+ const char *prefix,
+ git_oid_t oid_type,
+ unsigned int mode,
+ git_odb *odb,
+ git_indexer_options *in_opts)
{
git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT;
git_indexer *idx;
@@ -154,6 +156,7 @@ int git_indexer_new(
idx = git__calloc(1, sizeof(git_indexer));
GIT_ERROR_CHECK_ALLOC(idx);
+ idx->oid_type = oid_type;
idx->odb = odb;
idx->progress_cb = opts.progress_cb;
idx->progress_payload = opts.progress_cb_payload;
@@ -209,6 +212,33 @@ cleanup:
return -1;
}
+#ifdef GIT_EXPERIMENTAL_SHA256
+int git_indexer_new(
+ git_indexer **out,
+ const char *prefix,
+ git_oid_t oid_type,
+ git_indexer_options *opts)
+{
+ return indexer_new(
+ out,
+ prefix,
+ oid_type,
+ opts ? opts->mode : 0,
+ opts ? opts->odb : NULL,
+ opts);
+}
+#else
+int git_indexer_new(
+ git_indexer **out,
+ const char *prefix,
+ unsigned int mode,
+ git_odb *odb,
+ git_indexer_options *opts)
+{
+ return indexer_new(out, prefix, GIT_OID_SHA1, mode, odb, opts);
+}
+#endif
+
void git_indexer__set_fsync(git_indexer *idx, int do_fsync)
{
idx->do_fsync = !!do_fsync;
@@ -273,7 +303,7 @@ static int advance_delta_offset(git_indexer *idx, git_object_t type)
GIT_ASSERT_ARG(type == GIT_OBJECT_REF_DELTA || type == GIT_OBJECT_OFS_DELTA);
if (type == GIT_OBJECT_REF_DELTA) {
- idx->off += GIT_OID_SHA1_SIZE;
+ idx->off += git_oid_size(idx->oid_type);
} else {
off64_t base_off;
int error = get_delta_base(&base_off, idx->pack, &w, &idx->off, type, idx->entry_start);
@@ -357,7 +387,7 @@ static int check_object_connectivity(git_indexer *idx, const git_rawobj *obj)
obj->type != GIT_OBJECT_TAG)
return 0;
- if (git_object__from_raw(&object, obj->data, obj->len, obj->type) < 0) {
+ if (git_object__from_raw(&object, obj->data, obj->len, obj->type, idx->oid_type) < 0) {
/*
* parse_raw returns EINVALID on invalid data; downgrade
* that to a normal -1 error code.
@@ -447,7 +477,7 @@ static int store_object(git_indexer *idx)
}
#ifdef GIT_EXPERIMENTAL_SHA256
- oid.type = GIT_OID_SHA1;
+ oid.type = idx->oid_type;
#endif
entry_size = idx->off - entry_start;
@@ -550,7 +580,7 @@ static int hash_and_save(git_indexer *idx, git_rawobj *obj, off64_t entry_start)
entry = git__calloc(1, sizeof(*entry));
GIT_ERROR_CHECK_ALLOC(entry);
- if (git_odb__hashobj(&oid, obj, GIT_OID_SHA1) < 0) {
+ if (git_odb__hashobj(&oid, obj, idx->oid_type) < 0) {
git_error_set(GIT_ERROR_INDEXER, "failed to hash object");
goto on_error;
}
@@ -588,30 +618,31 @@ static int do_progress_callback(git_indexer *idx, git_indexer_progress *stats)
static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
{
size_t to_expell, to_keep;
+ size_t oid_size = git_oid_size(idx->oid_type);
if (size == 0)
return;
/* Easy case, dump the buffer and the data minus the last 20 bytes */
- if (size >= GIT_OID_SHA1_SIZE) {
+ if (size >= oid_size) {
git_hash_update(&idx->trailer, idx->inbuf, idx->inbuf_len);
- git_hash_update(&idx->trailer, data, size - GIT_OID_SHA1_SIZE);
+ git_hash_update(&idx->trailer, data, size - oid_size);
- data += size - GIT_OID_SHA1_SIZE;
- memcpy(idx->inbuf, data, GIT_OID_SHA1_SIZE);
- idx->inbuf_len = GIT_OID_SHA1_SIZE;
+ data += size - oid_size;
+ memcpy(idx->inbuf, data, oid_size);
+ idx->inbuf_len = oid_size;
return;
}
/* We can just append */
- if (idx->inbuf_len + size <= GIT_OID_SHA1_SIZE) {
+ if (idx->inbuf_len + size <= oid_size) {
memcpy(idx->inbuf + idx->inbuf_len, data, size);
idx->inbuf_len += size;
return;
}
/* We need to partially drain the buffer and then append */
- to_keep = GIT_OID_SHA1_SIZE - size;
+ to_keep = oid_size - size;
to_expell = idx->inbuf_len - to_keep;
git_hash_update(&idx->trailer, idx->inbuf, to_expell);
@@ -906,7 +937,7 @@ static int index_path(git_str *path, git_indexer *idx, const char *suffix)
slash--;
if (git_str_grow(path, slash + 1 + strlen(prefix) +
- GIT_OID_SHA1_HEXSIZE + strlen(suffix) + 1) < 0)
+ git_oid_hexsize(idx->oid_type) + strlen(suffix) + 1) < 0)
return -1;
git_str_truncate(path, slash);
@@ -923,7 +954,7 @@ static int index_path(git_str *path, git_indexer *idx, const char *suffix)
*/
static int seek_back_trailer(git_indexer *idx)
{
- idx->pack->mwf.size -= GIT_OID_SHA1_SIZE;
+ idx->pack->mwf.size -= git_oid_size(idx->oid_type);
return git_mwindow_free_all(&idx->pack->mwf);
}
@@ -983,7 +1014,7 @@ static int inject_object(git_indexer *idx, git_oid *id)
if ((error = append_to_pack(idx, empty_checksum, checksum_size)) < 0)
goto cleanup;
- idx->pack->mwf.size += GIT_OID_SHA1_SIZE;
+ idx->pack->mwf.size += git_oid_size(idx->oid_type);
pentry = git__calloc(1, sizeof(struct git_pack_entry));
GIT_ERROR_CHECK_ALLOC(pentry);
@@ -1046,13 +1077,13 @@ static int fix_thin_pack(git_indexer *idx, git_indexer_progress *stats)
}
/* curpos now points to the base information, which is an OID */
- base_info = git_mwindow_open(&idx->pack->mwf, &w, curpos, GIT_OID_SHA1_SIZE, &left);
+ base_info = git_mwindow_open(&idx->pack->mwf, &w, curpos, git_oid_size(idx->oid_type), &left);
if (base_info == NULL) {
git_error_set(GIT_ERROR_INDEXER, "failed to map delta information");
return -1;
}
- git_oid__fromraw(&base, base_info, GIT_OID_SHA1);
+ git_oid__fromraw(&base, base_info, idx->oid_type);
git_mwindow_close(&w);
if (has_entry(idx, &base))
@@ -1275,7 +1306,7 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
/* Write out the object names (SHA-1 hashes) */
git_vector_foreach(&idx->objects, i, entry) {
- git_filebuf_write(&index_file, &entry->oid.id, GIT_OID_SHA1_SIZE);
+ git_filebuf_write(&index_file, &entry->oid.id, git_oid_size(idx->oid_type));
}
/* Write out the CRC32 values */
diff --git a/src/libgit2/object.c b/src/libgit2/object.c
index d45465678..d87d40cf1 100644
--- a/src/libgit2/object.c
+++ b/src/libgit2/object.c
@@ -27,8 +27,8 @@ typedef struct {
const char *str; /* type name string */
size_t size; /* size in bytes of the object structure */
- int (*parse)(void *self, git_odb_object *obj);
- int (*parse_raw)(void *self, const char *data, size_t size);
+ int (*parse)(void *self, git_odb_object *obj, git_oid_t oid_type);
+ int (*parse_raw)(void *self, const char *data, size_t size, git_oid_t oid_type);
void (*free)(void *self);
} git_object_def;
@@ -60,7 +60,8 @@ int git_object__from_raw(
git_object **object_out,
const char *data,
size_t size,
- git_object_t type)
+ git_object_t object_type,
+ git_oid_t oid_type)
{
git_object_def *def;
git_object *object;
@@ -71,12 +72,15 @@ int git_object__from_raw(
*object_out = NULL;
/* Validate type match */
- if (type != GIT_OBJECT_BLOB && type != GIT_OBJECT_TREE && type != GIT_OBJECT_COMMIT && type != GIT_OBJECT_TAG) {
+ if (object_type != GIT_OBJECT_BLOB &&
+ object_type != GIT_OBJECT_TREE &&
+ object_type != GIT_OBJECT_COMMIT &&
+ object_type != GIT_OBJECT_TAG) {
git_error_set(GIT_ERROR_INVALID, "the requested type is invalid");
return GIT_ENOTFOUND;
}
- if ((object_size = git_object__size(type)) == 0) {
+ if ((object_size = git_object__size(object_type)) == 0) {
git_error_set(GIT_ERROR_INVALID, "the requested type is invalid");
return GIT_ENOTFOUND;
}
@@ -85,15 +89,15 @@ int git_object__from_raw(
object = git__calloc(1, object_size);
GIT_ERROR_CHECK_ALLOC(object);
object->cached.flags = GIT_CACHE_STORE_PARSED;
- object->cached.type = type;
- if ((error = git_odb__hash(&object->cached.oid, data, size, type, GIT_OID_SHA1)) < 0)
+ object->cached.type = object_type;
+ if ((error = git_odb__hash(&object->cached.oid, data, size, object_type, oid_type)) < 0)
return error;
/* Parse raw object data */
- def = &git_objects_table[type];
+ def = &git_objects_table[object_type];
GIT_ASSERT(def->free && def->parse_raw);
- if ((error = def->parse_raw(object, data, size)) < 0) {
+ if ((error = def->parse_raw(object, data, size, oid_type)) < 0) {
def->free(object);
return error;
}
@@ -143,7 +147,7 @@ int git_object__from_odb_object(
def = &git_objects_table[odb_obj->cached.type];
GIT_ASSERT(def->free && def->parse);
- if ((error = def->parse(object, odb_obj)) < 0) {
+ if ((error = def->parse(object, odb_obj, repo->oid_type)) < 0) {
/*
* parse returns EINVALID on invalid data; downgrade
* that to a normal -1 error code.
@@ -357,12 +361,11 @@ static int dereference_object(git_object **dereferenced, git_object *obj)
static int peel_error(int error, const git_oid *oid, git_object_t type)
{
const char *type_name;
- char hex_oid[GIT_OID_SHA1_HEXSIZE + 1];
+ char hex_oid[GIT_OID_MAX_HEXSIZE + 1];
type_name = git_object_type2string(type);
- git_oid_fmt(hex_oid, oid);
- hex_oid[GIT_OID_SHA1_HEXSIZE] = '\0';
+ git_oid_nfmt(hex_oid, GIT_OID_MAX_HEXSIZE + 1, oid);
git_error_set(GIT_ERROR_OBJECT, "the git_object of id '%s' can not be "
"successfully peeled into a %s (git_object_t=%i).", hex_oid, type_name, type);
@@ -576,21 +579,29 @@ int git_object_rawcontent_is_valid(
int *valid,
const char *buf,
size_t len,
- git_object_t type)
+ git_object_t object_type
+#ifdef GIT_EXPERIMENTAL_SHA256
+ , git_oid_t oid_type
+#endif
+ )
{
git_object *obj = NULL;
int error;
+#ifndef GIT_EXPERIMENTAL_SHA256
+ git_oid_t oid_type = GIT_OID_SHA1;
+#endif
+
GIT_ASSERT_ARG(valid);
GIT_ASSERT_ARG(buf);
/* Blobs are always valid; don't bother parsing. */
- if (type == GIT_OBJECT_BLOB) {
+ if (object_type == GIT_OBJECT_BLOB) {
*valid = 1;
return 0;
}
- error = git_object__from_raw(&obj, buf, len, type);
+ error = git_object__from_raw(&obj, buf, len, object_type, oid_type);
git_object_free(obj);
if (error == 0) {
@@ -611,7 +622,7 @@ int git_object__parse_oid_header(
const char *header,
git_oid_t oid_type)
{
- const size_t sha_len = GIT_OID_SHA1_HEXSIZE;
+ const size_t sha_len = git_oid_hexsize(oid_type);
const size_t header_len = strlen(header);
const char *buffer = *buffer_out;
diff --git a/src/libgit2/object.h b/src/libgit2/object.h
index 980e8627e..a29fdfbf3 100644
--- a/src/libgit2/object.h
+++ b/src/libgit2/object.h
@@ -33,7 +33,8 @@ int git_object__from_raw(
git_object **object_out,
const char *data,
size_t size,
- git_object_t type);
+ git_object_t object_type,
+ git_oid_t oid_type);
int git_object__from_odb_object(
git_object **object_out,
diff --git a/src/libgit2/odb_pack.c b/src/libgit2/odb_pack.c
index 814c0bc75..1b1d122b0 100644
--- a/src/libgit2/odb_pack.c
+++ b/src/libgit2/odb_pack.c
@@ -718,6 +718,7 @@ static int pack_backend__writepack(struct git_odb_writepack **out,
git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT;
struct pack_backend *backend;
struct pack_writepack *writepack;
+ int error;
GIT_ASSERT_ARG(out);
GIT_ASSERT_ARG(_backend);
@@ -732,11 +733,20 @@ static int pack_backend__writepack(struct git_odb_writepack **out,
writepack = git__calloc(1, sizeof(struct pack_writepack));
GIT_ERROR_CHECK_ALLOC(writepack);
- if (git_indexer_new(&writepack->indexer,
- backend->pack_folder, 0, odb, &opts) < 0) {
- git__free(writepack);
+#ifdef GIT_EXPERIMENTAL_SHA256
+ opts.odb = odb;
+
+ error = git_indexer_new(&writepack->indexer,
+ backend->pack_folder,
+ backend->opts.oid_type,
+ &opts);
+#else
+ error = git_indexer_new(&writepack->indexer,
+ backend->pack_folder, 0, odb, &opts);
+#endif
+
+ if (error < 0)
return -1;
- }
writepack->parent.backend = _backend;
writepack->parent.append = pack_backend__writepack_append;
diff --git a/src/libgit2/pack-objects.c b/src/libgit2/pack-objects.c
index 068231649..20a5dfcbd 100644
--- a/src/libgit2/pack-objects.c
+++ b/src/libgit2/pack-objects.c
@@ -1407,7 +1407,18 @@ int git_packbuilder_write(
opts.progress_cb = progress_cb;
opts.progress_cb_payload = progress_cb_payload;
- if ((error = git_indexer_new(&indexer, path, mode, pb->odb, &opts)) < 0)
+ /* TODO: SHA256 */
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ opts.mode = mode;
+ opts.odb = pb->odb;
+
+ error = git_indexer_new(&indexer, path, GIT_OID_SHA1, &opts);
+#else
+ error = git_indexer_new(&indexer, path, mode, pb->odb, &opts);
+#endif
+
+ if (error < 0)
goto cleanup;
if (!git_repository__configmap_lookup(&t, pb->repo, GIT_CONFIGMAP_FSYNCOBJECTFILES) && t)
diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c
index 043cfd1fd..2da6caf3a 100644
--- a/src/libgit2/repository.c
+++ b/src/libgit2/repository.c
@@ -1278,11 +1278,14 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
*out = git_atomic_load(repo->_odb);
if (*out == NULL) {
git_str odb_path = GIT_STR_INIT;
+ git_odb_options odb_opts = GIT_ODB_OPTIONS_INIT;
git_odb *odb;
+ odb_opts.oid_type = repo->oid_type;
+
if ((error = git_repository__item_path(&odb_path, repo,
GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
- (error = git_odb__new(&odb, NULL)) < 0)
+ (error = git_odb__new(&odb, &odb_opts)) < 0)
return error;
GIT_REFCOUNT_OWN(odb, repo);
diff --git a/src/libgit2/tag.c b/src/libgit2/tag.c
index 0a90e393c..562ec13ea 100644
--- a/src/libgit2/tag.c
+++ b/src/libgit2/tag.c
@@ -65,7 +65,11 @@ static int tag_error(const char *str)
return GIT_EINVALID;
}
-static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
+static int tag_parse(
+ git_tag *tag,
+ const char *buffer,
+ const char *buffer_end,
+ git_oid_t oid_type)
{
static const char *tag_types[] = {
NULL, "commit\n", "tree\n", "blob\n", "tag\n"
@@ -76,7 +80,7 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
int error;
if (git_object__parse_oid_header(&tag->target,
- &buffer, buffer_end, "object ", GIT_OID_SHA1) < 0)
+ &buffer, buffer_end, "object ", oid_type) < 0)
return tag_error("object field invalid");
if (buffer + 5 >= buffer_end)
@@ -161,18 +165,25 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
return 0;
}
-int git_tag__parse_raw(void *_tag, const char *data, size_t size)
+int git_tag__parse_raw(
+ void *_tag,
+ const char *data,
+ size_t size,
+ git_oid_t oid_type)
{
- return tag_parse(_tag, data, data + size);
+ return tag_parse(_tag, data, data + size, oid_type);
}
-int git_tag__parse(void *_tag, git_odb_object *odb_obj)
+int git_tag__parse(
+ void *_tag,
+ git_odb_object *odb_obj,
+ git_oid_t oid_type)
{
git_tag *tag = _tag;
const char *buffer = git_odb_object_data(odb_obj);
const char *buffer_end = buffer + git_odb_object_size(odb_obj);
- return tag_parse(tag, buffer, buffer_end);
+ return tag_parse(tag, buffer, buffer_end, oid_type);
}
static int retrieve_tag_reference(
@@ -374,7 +385,7 @@ int git_tag_create_from_buffer(git_oid *oid, git_repository *repo, const char *b
return -1;
/* validate the buffer */
- if (tag_parse(&tag, buffer, buffer + strlen(buffer)) < 0)
+ if (tag_parse(&tag, buffer, buffer + strlen(buffer), repo->oid_type) < 0)
return -1;
/* validate the target */
diff --git a/src/libgit2/tag.h b/src/libgit2/tag.h
index 76ae1508e..fdaaa463c 100644
--- a/src/libgit2/tag.h
+++ b/src/libgit2/tag.h
@@ -25,7 +25,7 @@ struct git_tag {
};
void git_tag__free(void *tag);
-int git_tag__parse(void *tag, git_odb_object *obj);
-int git_tag__parse_raw(void *tag, const char *data, size_t size);
+int git_tag__parse(void *tag, git_odb_object *obj, git_oid_t oid_type);
+int git_tag__parse_raw(void *tag, const char *data, size_t size, git_oid_t oid_type);
#endif
diff --git a/src/libgit2/tree.c b/src/libgit2/tree.c
index 9a43d585c..9293d9422 100644
--- a/src/libgit2/tree.c
+++ b/src/libgit2/tree.c
@@ -85,11 +85,17 @@ static git_tree_entry *alloc_entry(const char *filename, size_t filename_len, co
char *filename_ptr;
size_t tree_len;
+#ifdef GIT_EXPERIMENTAL_SHA256
+ size_t oid_size = git_oid_size(id->type);
+#else
+ size_t oid_size = GIT_OID_SHA1_SIZE;
+#endif
+
TREE_ENTRY_CHECK_NAMELEN(filename_len);
if (GIT_ADD_SIZET_OVERFLOW(&tree_len, sizeof(git_tree_entry), filename_len) ||
GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, 1) ||
- GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, GIT_OID_SHA1_SIZE))
+ GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, oid_size))
return NULL;
entry = git__calloc(1, tree_len);
@@ -383,11 +389,12 @@ static int parse_mode(uint16_t *mode_out, const char *buffer, size_t buffer_len,
return 0;
}
-int git_tree__parse_raw(void *_tree, const char *data, size_t size)
+int git_tree__parse_raw(void *_tree, const char *data, size_t size, git_oid_t oid_type)
{
git_tree *tree = _tree;
const char *buffer;
const char *buffer_end;
+ const long oid_size = (long)git_oid_size(oid_type);
buffer = data;
buffer_end = buffer + size;
@@ -414,35 +421,33 @@ int git_tree__parse_raw(void *_tree, const char *data, size_t size)
if ((filename_len = nul - buffer) == 0 || filename_len > UINT16_MAX)
return tree_parse_error("failed to parse tree: can't parse filename", NULL);
- if ((buffer_end - (nul + 1)) < GIT_OID_SHA1_SIZE)
+ if ((buffer_end - (nul + 1)) < (long)oid_size)
return tree_parse_error("failed to parse tree: can't parse OID", NULL);
/* Allocate the entry */
- {
- entry = git_array_alloc(tree->entries);
- GIT_ERROR_CHECK_ALLOC(entry);
-
- entry->attr = attr;
- entry->filename_len = (uint16_t)filename_len;
- entry->filename = buffer;
- git_oid__fromraw(&entry->oid, ((unsigned char *) buffer + filename_len + 1), GIT_OID_SHA1);
- }
+ entry = git_array_alloc(tree->entries);
+ GIT_ERROR_CHECK_ALLOC(entry);
+ entry->attr = attr;
+ entry->filename_len = (uint16_t)filename_len;
+ entry->filename = buffer;
buffer += filename_len + 1;
- buffer += GIT_OID_SHA1_SIZE;
+
+ git_oid__fromraw(&entry->oid, (unsigned char *)buffer, oid_type);
+ buffer += oid_size;
}
return 0;
}
-int git_tree__parse(void *_tree, git_odb_object *odb_obj)
+int git_tree__parse(void *_tree, git_odb_object *odb_obj, git_oid_t oid_type)
{
git_tree *tree = _tree;
const char *data = git_odb_object_data(odb_obj);
size_t size = git_odb_object_size(odb_obj);
int error;
- if ((error = git_tree__parse_raw(tree, data, size)) < 0 ||
+ if ((error = git_tree__parse_raw(tree, data, size, oid_type)) < 0 ||
(error = git_odb_object_dup(&tree->odb_obj, odb_obj)) < 0)
return error;
@@ -506,6 +511,7 @@ static int git_treebuilder__write_with_buffer(
git_odb *odb;
git_tree_entry *entry;
git_vector entries = GIT_VECTOR_INIT;
+ size_t oid_size = git_oid_size(bld->repo->oid_type);
git_str_clear(buf);
@@ -529,7 +535,7 @@ static int git_treebuilder__write_with_buffer(
git_str_printf(buf, "%o ", entry->attr);
git_str_put(buf, entry->filename, entry->filename_len + 1);
- git_str_put(buf, (char *)entry->oid.id, GIT_OID_SHA1_SIZE);
+ git_str_put(buf, (char *)entry->oid.id, oid_size);
if (git_str_oom(buf)) {
error = -1;
diff --git a/src/libgit2/tree.h b/src/libgit2/tree.h
index 0dd963ff2..5088450ab 100644
--- a/src/libgit2/tree.h
+++ b/src/libgit2/tree.h
@@ -41,8 +41,8 @@ GIT_INLINE(bool) git_tree_entry__is_tree(const struct git_tree_entry *e)
}
void git_tree__free(void *tree);
-int git_tree__parse(void *tree, git_odb_object *obj);
-int git_tree__parse_raw(void *_tree, const char *data, size_t size);
+int git_tree__parse(void *tree, git_odb_object *obj, git_oid_t oid_type);
+int git_tree__parse_raw(void *_tree, const char *data, size_t size, git_oid_t oid_type);
/**
* Write a tree to the given repository
diff --git a/tests/libgit2/commit/parse.c b/tests/libgit2/commit/parse.c
index b313fc308..3a1fc3d26 100644
--- a/tests/libgit2/commit/parse.c
+++ b/tests/libgit2/commit/parse.c
@@ -287,7 +287,7 @@ static int parse_commit(git_commit **out, const char *buffer)
fake_odb_object.buffer = (char *)buffer;
fake_odb_object.cached.size = strlen(fake_odb_object.buffer);
- error = git_commit__parse(commit, &fake_odb_object);
+ error = git_commit__parse(commit, &fake_odb_object, GIT_OID_SHA1);
*out = commit;
return error;
diff --git a/tests/libgit2/object/commit/parse.c b/tests/libgit2/object/commit/parse.c
index 28a3ccd85..6f9a65507 100644
--- a/tests/libgit2/object/commit/parse.c
+++ b/tests/libgit2/object/commit/parse.c
@@ -3,7 +3,10 @@
#include "object.h"
#include "signature.h"
-static void assert_commit_parses(const char *data, size_t datalen,
+static void assert_commit_parses(
+ const char *data,
+ size_t datalen,
+ git_oid_t oid_type,
const char *expected_treeid,
const char *expected_author,
const char *expected_committer,
@@ -14,7 +17,7 @@ static void assert_commit_parses(const char *data, size_t datalen,
git_commit *commit;
if (!datalen)
datalen = strlen(data);
- cl_git_pass(git_object__from_raw((git_object **) &commit, data, datalen, GIT_OBJECT_COMMIT));
+ cl_git_pass(git_object__from_raw((git_object **) &commit, data, datalen, GIT_OBJECT_COMMIT, oid_type));
if (expected_author) {
git_signature *author;
@@ -51,7 +54,7 @@ static void assert_commit_parses(const char *data, size_t datalen,
if (expected_treeid) {
git_oid tree_oid;
- cl_git_pass(git_oid__fromstr(&tree_oid, expected_treeid, GIT_OID_SHA1));
+ cl_git_pass(git_oid__fromstr(&tree_oid, expected_treeid, oid_type));
cl_assert_equal_oid(&tree_oid, &commit->tree_id);
}
@@ -60,15 +63,18 @@ static void assert_commit_parses(const char *data, size_t datalen,
git_object__free(&commit->object);
}
-static void assert_commit_fails(const char *data, size_t datalen)
+static void assert_commit_fails(
+ const char *data,
+ size_t datalen,
+ git_oid_t oid_type)
{
git_object *object;
if (!datalen)
datalen = strlen(data);
- cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_COMMIT));
+ cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_COMMIT, oid_type));
}
-void test_object_commit_parse__parsing_commit_succeeds(void)
+void test_object_commit_parse__sha1_parsing_commit_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
@@ -77,7 +83,7 @@ void test_object_commit_parse__parsing_commit_succeeds(void)
"encoding Encoding\n"
"\n"
"Message";
- assert_commit_parses(commit, 0,
+ assert_commit_parses(commit, 0, GIT_OID_SHA1,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer <committer@example.com>",
@@ -85,7 +91,7 @@ void test_object_commit_parse__parsing_commit_succeeds(void)
"Message", 0);
}
-void test_object_commit_parse__parsing_commit_without_encoding_succeeds(void)
+void test_object_commit_parse__sha1_parsing_commit_without_encoding_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
@@ -93,7 +99,7 @@ void test_object_commit_parse__parsing_commit_without_encoding_succeeds(void)
"committer Committer <committer@example.com>\n"
"\n"
"Message";
- assert_commit_parses(commit, 0,
+ assert_commit_parses(commit, 0, GIT_OID_SHA1,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer <committer@example.com>",
@@ -101,7 +107,7 @@ void test_object_commit_parse__parsing_commit_without_encoding_succeeds(void)
"Message", 0);
}
-void test_object_commit_parse__parsing_commit_with_multiple_authors_succeeds(void)
+void test_object_commit_parse__sha1_parsing_commit_with_multiple_authors_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
@@ -112,7 +118,7 @@ void test_object_commit_parse__parsing_commit_with_multiple_authors_succeeds(voi
"committer Committer <committer@example.com>\n"
"\n"
"Message";
- assert_commit_parses(commit, 0,
+ assert_commit_parses(commit, 0, GIT_OID_SHA1,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author1 <author@example.com>",
"Committer <committer@example.com>",
@@ -120,7 +126,7 @@ void test_object_commit_parse__parsing_commit_with_multiple_authors_succeeds(voi
"Message", 0);
}
-void test_object_commit_parse__parsing_commit_with_multiple_committers_succeeds(void)
+void test_object_commit_parse__sha1_parsing_commit_with_multiple_committers_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
@@ -131,7 +137,7 @@ void test_object_commit_parse__parsing_commit_with_multiple_committers_succeeds(
"committer Committer4 <committer@example.com>\n"
"\n"
"Message";
- assert_commit_parses(commit, 0,
+ assert_commit_parses(commit, 0, GIT_OID_SHA1,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer1 <committer@example.com>",
@@ -139,13 +145,13 @@ void test_object_commit_parse__parsing_commit_with_multiple_committers_succeeds(
"Message", 0);
}
-void test_object_commit_parse__parsing_commit_without_message_succeeds(void)
+void test_object_commit_parse__sha1_parsing_commit_without_message_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"committer Committer <committer@example.com>\n";
- assert_commit_parses(commit, 0,
+ assert_commit_parses(commit, 0, GIT_OID_SHA1,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer <committer@example.com>",
@@ -153,7 +159,7 @@ void test_object_commit_parse__parsing_commit_without_message_succeeds(void)
"", 0);
}
-void test_object_commit_parse__parsing_commit_with_unknown_fields_succeeds(void)
+void test_object_commit_parse__sha1_parsing_commit_with_unknown_fields_succeeds(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
@@ -163,7 +169,7 @@ void test_object_commit_parse__parsing_commit_with_unknown_fields_succeeds(void)
"more garbage\n"
"\n"
"Message";
- assert_commit_parses(commit, 0,
+ assert_commit_parses(commit, 0, GIT_OID_SHA1,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"Author <author@example.com>",
"Committer <committer@example.com>",
@@ -171,7 +177,7 @@ void test_object_commit_parse__parsing_commit_with_unknown_fields_succeeds(void)
"Message", 0);
}
-void test_object_commit_parse__parsing_commit_with_invalid_tree_fails(void)
+void test_object_commit_parse__sha1_parsing_commit_with_invalid_tree_fails(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1xxx5f3445895b71d9cb0f8\n"
@@ -179,40 +185,51 @@ void test_object_commit_parse__parsing_commit_with_invalid_tree_fails(void)
"committer Committer <committer@example.com>\n"
"\n"
"Message";
- assert_commit_fails(commit, 0);
+ assert_commit_fails(commit, 0, GIT_OID_SHA1);
}
-void test_object_commit_parse__parsing_commit_without_tree_fails(void)
+void test_object_commit_parse__sha1_parsing_commit_with_sha256_tree_fails(void)
{
const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
"author Author <author@example.com>\n"
"committer Committer <committer@example.com>\n"
"\n"
"Message";
- assert_commit_fails(commit, 0);
+ assert_commit_fails(commit, 0, GIT_OID_SHA1);
}
-void test_object_commit_parse__parsing_commit_without_author_fails(void)
+void test_object_commit_parse__sha1_parsing_commit_without_tree_fails(void)
+{
+ const char *commit =
+ "author Author <author@example.com>\n"
+ "committer Committer <committer@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_fails(commit, 0, GIT_OID_SHA1);
+}
+
+void test_object_commit_parse__sha1_parsing_commit_without_author_fails(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"committer Committer <committer@example.com>\n"
"\n"
"Message";
- assert_commit_fails(commit, 0);
+ assert_commit_fails(commit, 0, GIT_OID_SHA1);
}
-void test_object_commit_parse__parsing_commit_without_committer_fails(void)
+void test_object_commit_parse__sha1_parsing_commit_without_committer_fails(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
"author Author <author@example.com>\n"
"\n"
"Message";
- assert_commit_fails(commit, 0);
+ assert_commit_fails(commit, 0, GIT_OID_SHA1);
}
-void test_object_commit_parse__parsing_encoding_will_not_cause_oob_read(void)
+void test_object_commit_parse__sha1_parsing_encoding_will_not_cause_oob_read(void)
{
const char *commit =
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
@@ -223,10 +240,237 @@ void test_object_commit_parse__parsing_encoding_will_not_cause_oob_read(void)
* As we ignore unknown fields, the cut-off encoding field will be
* parsed just fine.
*/
- assert_commit_parses(commit, strlen(commit) - strlen("ncoding foo\n"),
+ assert_commit_parses(
+ commit, strlen(commit) - strlen("ncoding foo\n"),
+ GIT_OID_SHA1,
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
"<>",
"<>",
NULL,
"", 0);
}
+
+
+void test_object_commit_parse__sha256_parsing_commit_succeeds(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author Author <author@example.com>\n"
+ "committer Committer <committer@example.com>\n"
+ "encoding Encoding\n"
+ "\n"
+ "Message";
+ assert_commit_parses(commit, 0, GIT_OID_SHA256,
+ "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736",
+ "Author <author@example.com>",
+ "Committer <committer@example.com>",
+ "Encoding",
+ "Message", 0);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_without_encoding_succeeds(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author Author <author@example.com>\n"
+ "committer Committer <committer@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_parses(commit, 0, GIT_OID_SHA256,
+ "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736",
+ "Author <author@example.com>",
+ "Committer <committer@example.com>",
+ NULL,
+ "Message", 0);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_with_multiple_authors_succeeds(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author Author1 <author@example.com>\n"
+ "author Author2 <author@example.com>\n"
+ "author Author3 <author@example.com>\n"
+ "author Author4 <author@example.com>\n"
+ "committer Committer <committer@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_parses(commit, 0, GIT_OID_SHA256,
+ "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736",
+ "Author1 <author@example.com>",
+ "Committer <committer@example.com>",
+ NULL,
+ "Message", 0);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_with_multiple_committers_succeeds(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author Author <author@example.com>\n"
+ "committer Committer1 <committer@example.com>\n"
+ "committer Committer2 <committer@example.com>\n"
+ "committer Committer3 <committer@example.com>\n"
+ "committer Committer4 <committer@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_parses(commit, 0, GIT_OID_SHA256,
+ "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736",
+ "Author <author@example.com>",
+ "Committer1 <committer@example.com>",
+ NULL,
+ "Message", 0);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_without_message_succeeds(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author Author <author@example.com>\n"
+ "committer Committer <committer@example.com>\n";
+ assert_commit_parses(commit, 0, GIT_OID_SHA256,
+ "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736",
+ "Author <author@example.com>",
+ "Committer <committer@example.com>",
+ NULL,
+ "", 0);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_with_unknown_fields_succeeds(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author Author <author@example.com>\n"
+ "committer Committer <committer@example.com>\n"
+ "foo bar\n"
+ "more garbage\n"
+ "\n"
+ "Message";
+ assert_commit_parses(commit, 0, GIT_OID_SHA256,
+ "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736",
+ "Author <author@example.com>",
+ "Committer <committer@example.com>",
+ NULL,
+ "Message", 0);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_with_invalid_tree_fails(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9adxxxd55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author Author <author@example.com>\n"
+ "committer Committer <committer@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_fails(commit, 0, GIT_OID_SHA256);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_with_sha1_tree_fails(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
+ "author Author <author@example.com>\n"
+ "committer Committer <committer@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_fails(commit, 0, GIT_OID_SHA256);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_without_tree_fails(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "author Author <author@example.com>\n"
+ "committer Committer <committer@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_fails(commit, 0, GIT_OID_SHA256);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_without_author_fails(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "committer Committer <committer@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_fails(commit, 0, GIT_OID_SHA256);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_commit_without_committer_fails(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author Author <author@example.com>\n"
+ "\n"
+ "Message";
+ assert_commit_fails(commit, 0, GIT_OID_SHA256);
+#endif
+}
+
+void test_object_commit_parse__sha256_parsing_encoding_will_not_cause_oob_read(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit =
+ "tree f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736\n"
+ "author <>\n"
+ "committer <>\n"
+ "encoding foo\n";
+ /*
+ * As we ignore unknown fields, the cut-off encoding field will be
+ * parsed just fine.
+ */
+ assert_commit_parses(
+ commit, strlen(commit) - strlen("ncoding foo\n"),
+ GIT_OID_SHA256,
+ "f2a108f86a3b4fd9ad75ed55e9cb3cb46e348fca3b9dba3db64f7c9f64b8a736",
+ "<>",
+ "<>",
+ NULL,
+ "", 0);
+#endif
+}
diff --git a/tests/libgit2/object/lookup256.c b/tests/libgit2/object/lookup256.c
new file mode 100644
index 000000000..3e1dab661
--- /dev/null
+++ b/tests/libgit2/object/lookup256.c
@@ -0,0 +1,153 @@
+#include "clar_libgit2.h"
+
+#include "repository.h"
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+static git_repository *g_repo;
+#endif
+
+void test_object_lookup256__initialize(void)
+{
+#ifdef GIT_EXPERIMENTAL_SHA256
+ g_repo = cl_git_sandbox_init("testrepo_256.git");
+#endif
+}
+
+void test_object_lookup256__cleanup(void)
+{
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_sandbox_cleanup();
+#endif
+}
+
+void test_object_lookup256__lookup_wrong_type_returns_enotfound(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit = "4d46d9719e425ef2dfb5bfba098d0b62e21b2b92d0731892eef70db0870e3744";
+ git_oid oid;
+ git_object *object;
+
+ cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA256));
+ cl_assert_equal_i(
+ GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_TAG));
+#endif
+}
+
+void test_object_lookup256__lookup_nonexisting_returns_enotfound(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *unknown = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
+ git_oid oid;
+ git_object *object;
+
+ cl_git_pass(git_oid__fromstr(&oid, unknown, GIT_OID_SHA256));
+ cl_assert_equal_i(
+ GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_ANY));
+#endif
+}
+
+void test_object_lookup256__lookup_wrong_type_by_abbreviated_id_returns_enotfound(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit = "4d46d97";
+ git_oid oid;
+ git_object *object;
+
+ cl_git_pass(git_oid__fromstrn(&oid, commit, strlen(commit), GIT_OID_SHA256));
+ cl_assert_equal_i(
+ GIT_ENOTFOUND, git_object_lookup_prefix(&object, g_repo, &oid, strlen(commit), GIT_OBJECT_TAG));
+#endif
+}
+
+void test_object_lookup256__lookup_wrong_type_eventually_returns_enotfound(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit = "4d46d9719e425ef2dfb5bfba098d0b62e21b2b92d0731892eef70db0870e3744";
+ git_oid oid;
+ git_object *object;
+
+ cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA256));
+
+ cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
+ git_object_free(object);
+
+ cl_assert_equal_i(
+ GIT_ENOTFOUND, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_TAG));
+#endif
+}
+
+void test_object_lookup256__lookup_corrupt_object_returns_error(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *commit = "5ca8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848",
+ *file = "objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848";
+ git_str path = GIT_STR_INIT, contents = GIT_STR_INIT;
+ git_oid oid;
+ git_object *object;
+ size_t i;
+
+ cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA256));
+ cl_git_pass(git_str_joinpath(&path, git_repository_path(g_repo), file));
+ cl_git_pass(git_futils_readbuffer(&contents, path.ptr));
+
+ /* Corrupt and try to read the object */
+ for (i = 0; i < contents.size; i++) {
+ contents.ptr[i] ^= 0x1;
+ cl_git_pass(git_futils_writebuffer(&contents, path.ptr, O_RDWR, 0644));
+ cl_git_fail(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
+ contents.ptr[i] ^= 0x1;
+ }
+
+ /* Restore original content and assert we can read the object */
+ cl_git_pass(git_futils_writebuffer(&contents, path.ptr, O_RDWR, 0644));
+ cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
+
+ git_object_free(object);
+ git_str_dispose(&path);
+ git_str_dispose(&contents);
+#endif
+}
+
+void test_object_lookup256__lookup_object_with_wrong_hash_returns_error(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ const char *oldloose = "objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26848",
+ *newloose = "objects/5c/a8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26840",
+ *commit = "5ca8959deb2b8327458e0344523eb1ddeeef4bce03e35864640b452f84d26840";
+
+ git_str oldpath = GIT_STR_INIT, newpath = GIT_STR_INIT;
+ git_object *object;
+ git_oid oid;
+
+ cl_git_pass(git_oid__fromstr(&oid, commit, GIT_OID_SHA256));
+
+ /* Copy object to another location with wrong hash */
+ cl_git_pass(git_str_joinpath(&oldpath, git_repository_path(g_repo), oldloose));
+ cl_git_pass(git_str_joinpath(&newpath, git_repository_path(g_repo), newloose));
+ cl_git_pass(git_futils_cp(oldpath.ptr, newpath.ptr, 0644));
+
+ /* Verify that lookup fails due to a hashsum mismatch */
+ cl_git_fail_with(GIT_EMISMATCH, git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
+
+ /* Disable verification and try again */
+ cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0));
+ cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJECT_COMMIT));
+ cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1));
+
+ git_object_free(object);
+ git_str_dispose(&oldpath);
+ git_str_dispose(&newpath);
+#endif
+}
diff --git a/tests/libgit2/object/tag/parse.c b/tests/libgit2/object/tag/parse.c
index 92298b5ce..d7a4d85bf 100644
--- a/tests/libgit2/object/tag/parse.c
+++ b/tests/libgit2/object/tag/parse.c
@@ -14,7 +14,7 @@ static void assert_tag_parses(const char *data, size_t datalen,
if (!datalen)
datalen = strlen(data);
- cl_git_pass(git_object__from_raw((git_object **) &tag, data, datalen, GIT_OBJECT_TAG));
+ cl_git_pass(git_object__from_raw((git_object **) &tag, data, datalen, GIT_OBJECT_TAG, GIT_OID_SHA1));
cl_assert_equal_i(tag->type, GIT_OBJECT_TAG);
if (expected_oid) {
@@ -54,7 +54,7 @@ static void assert_tag_fails(const char *data, size_t datalen)
git_object *object;
if (!datalen)
datalen = strlen(data);
- cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TAG));
+ cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TAG, GIT_OID_SHA1));
}
void test_object_tag_parse__valid_tag_parses(void)
diff --git a/tests/libgit2/object/tree/parse.c b/tests/libgit2/object/tree/parse.c
index d6d6e5302..fc985d672 100644
--- a/tests/libgit2/object/tree/parse.c
+++ b/tests/libgit2/object/tree/parse.c
@@ -26,7 +26,7 @@ static void assert_tree_parses(const char *data, size_t datalen,
if (!datalen)
datalen = strlen(data);
- cl_git_pass(git_object__from_raw((git_object **) &tree, data, datalen, GIT_OBJECT_TREE));
+ cl_git_pass(git_object__from_raw((git_object **) &tree, data, datalen, GIT_OBJECT_TREE, GIT_OID_SHA1));
cl_assert_equal_i(git_tree_entrycount(tree), expected_nentries);
@@ -51,7 +51,7 @@ static void assert_tree_fails(const char *data, size_t datalen)
git_object *object;
if (!datalen)
datalen = strlen(data);
- cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TREE));
+ cl_git_fail(git_object__from_raw(&object, data, datalen, GIT_OBJECT_TREE, GIT_OID_SHA1));
}
void test_object_tree_parse__single_blob_parses(void)
diff --git a/tests/libgit2/object/validate.c b/tests/libgit2/object/validate.c
index 87193deb6..e11038115 100644
--- a/tests/libgit2/object/validate.c
+++ b/tests/libgit2/object/validate.c
@@ -1,50 +1,154 @@
#include "clar_libgit2.h"
-#define VALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \
- "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \
- "author Edward Thomson <ethomson@edwardthomson.com> 1638286404 -0500\n" \
- "committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \
- "\n" \
- "commit go here.\n"
-#define VALID_TREE "100644 HEADER\0\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"
-
-#define INVALID_COMMIT "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \
- "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \
- "committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \
- "\n" \
- "commit go here.\n"
-#define INVALID_TREE "100644 HEADER \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"
-
-void test_object_validate__valid(void)
+#define VALID_COMMIT_SHA1 \
+ "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \
+ "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \
+ "author Edward Thomson <ethomson@edwardthomson.com> 1638286404 -0500\n" \
+ "committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \
+ "\n" \
+ "commit go here.\n"
+
+#define VALID_TREE_SHA1 \
+ "100644 HEADER\0\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"
+
+#define INVALID_COMMIT_SHA1 \
+ "tree bdd24e358576f1baa275df98cdcaf3ac9a3f4233\n" \
+ "parent d6d956f1d66210bfcd0484166befab33b5987a39\n" \
+ "committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \
+ "\n" \
+ "commit go here.\n"
+
+#define INVALID_TREE_SHA1 \
+ "100644 HEADER \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"
+
+#define VALID_COMMIT_SHA256 \
+ "tree d0fc7f52dc42358506e7f3f3be72f5271994abb104b9397ab3e19bb42361504d\n" \
+ "parent 652412419a24ba62a1d897f40aeb80eecbf873797b04a1bbb8d71918653ef65b\n" \
+ "author Edward Thomson <ethomson@edwardthomson.com> 1638286404 -0500\n" \
+ "committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \
+ "\n" \
+ "commit go here.\n"
+
+#define VALID_TREE_SHA256 \
+ "100644 HEADER\0\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"
+
+#define INVALID_COMMIT_SHA256 \
+ "tree d0fc7f52dc42358506e7f3f3be72f5271994abb104b9397ab3e19bb42361504d\n" \
+ "parent 652412419a24ba62a1d897f40aeb80eecbf873797b04a1bbb8d71918653ef65b\n" \
+ "committer Edward Thomson <ethomson@edwardthomson.com> 1638324642 -0500\n" \
+ "\n" \
+ "commit go here.\n"
+
+#define INVALID_TREE_SHA256 \
+ "100644 HEADER \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42"
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+# define sha1_rawcontent_is_valid(v, c, l, t) \
+ git_object_rawcontent_is_valid(v, c, l, t, GIT_OID_SHA1)
+#else
+# define sha1_rawcontent_is_valid(v, c, l, t) \
+ git_object_rawcontent_is_valid(v, c, l, t)
+#endif
+
+void test_object_validate__valid_sha1(void)
+{
+ int valid;
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB));
+ cl_assert_equal_i(1, valid);
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB));
+ cl_assert_equal_i(1, valid);
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, VALID_COMMIT_SHA1, CONST_STRLEN(VALID_COMMIT_SHA1), GIT_OBJECT_COMMIT));
+ cl_assert_equal_i(1, valid);
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, VALID_TREE_SHA1, CONST_STRLEN(VALID_TREE_SHA1), GIT_OBJECT_TREE));
+ cl_assert_equal_i(1, valid);
+}
+
+void test_object_validate__cannot_parse_sha256_as_sha1(void)
+{
+ int valid;
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, VALID_COMMIT_SHA256, CONST_STRLEN(INVALID_COMMIT_SHA256), GIT_OBJECT_COMMIT));
+ cl_assert_equal_i(0, valid);
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, INVALID_TREE_SHA256, CONST_STRLEN(INVALID_TREE_SHA256), GIT_OBJECT_TREE));
+ cl_assert_equal_i(0, valid);
+}
+
+void test_object_validate__invalid_sha1(void)
{
int valid;
- cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB));
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT));
+ cl_assert_equal_i(0, valid);
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT));
+ cl_assert_equal_i(0, valid);
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, INVALID_COMMIT_SHA1, CONST_STRLEN(INVALID_COMMIT_SHA1), GIT_OBJECT_COMMIT));
+ cl_assert_equal_i(0, valid);
+
+ cl_git_pass(sha1_rawcontent_is_valid(&valid, INVALID_TREE_SHA1, CONST_STRLEN(INVALID_TREE_SHA1), GIT_OBJECT_TREE));
+ cl_assert_equal_i(0, valid);
+}
+
+
+void test_object_validate__valid_sha256(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ int valid;
+
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_BLOB, GIT_OID_SHA256));
cl_assert_equal_i(1, valid);
- cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB));
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_BLOB, GIT_OID_SHA256));
cl_assert_equal_i(1, valid);
- cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT, CONST_STRLEN(VALID_COMMIT), GIT_OBJECT_COMMIT));
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT_SHA256, CONST_STRLEN(VALID_COMMIT_SHA256), GIT_OBJECT_COMMIT, GIT_OID_SHA256));
cl_assert_equal_i(1, valid);
- cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_TREE, CONST_STRLEN(VALID_TREE), GIT_OBJECT_TREE));
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_TREE_SHA256, CONST_STRLEN(VALID_TREE_SHA256), GIT_OBJECT_TREE, GIT_OID_SHA256));
cl_assert_equal_i(1, valid);
+#endif
}
-void test_object_validate__invalid(void)
+void test_object_validate__invalid_sha256(void)
{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
int valid;
- cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT));
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, "", 0, GIT_OBJECT_COMMIT, GIT_OID_SHA256));
+ cl_assert_equal_i(0, valid);
+
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT, GIT_OID_SHA256));
cl_assert_equal_i(0, valid);
- cl_git_pass(git_object_rawcontent_is_valid(&valid, "foobar", 0, GIT_OBJECT_COMMIT));
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_COMMIT_SHA256, CONST_STRLEN(INVALID_COMMIT_SHA256), GIT_OBJECT_COMMIT, GIT_OID_SHA256));
cl_assert_equal_i(0, valid);
- cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_COMMIT, CONST_STRLEN(INVALID_COMMIT), GIT_OBJECT_COMMIT));
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE_SHA256, CONST_STRLEN(INVALID_TREE_SHA256), GIT_OBJECT_TREE, GIT_OID_SHA256));
+ cl_assert_equal_i(0, valid);
+#endif
+}
+
+void test_object_validate__cannot_parse_sha1_as_sha256(void)
+{
+#ifndef GIT_EXPERIMENTAL_SHA256
+ cl_skip();
+#else
+ int valid;
+
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, VALID_COMMIT_SHA1, CONST_STRLEN(INVALID_COMMIT_SHA1), GIT_OBJECT_COMMIT, GIT_OID_SHA256));
cl_assert_equal_i(0, valid);
- cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE, CONST_STRLEN(INVALID_TREE), GIT_OBJECT_TREE));
+ cl_git_pass(git_object_rawcontent_is_valid(&valid, INVALID_TREE_SHA1, CONST_STRLEN(INVALID_TREE_SHA1), GIT_OBJECT_TREE, GIT_OID_SHA256));
cl_assert_equal_i(0, valid);
+#endif
}
diff --git a/tests/libgit2/pack/indexer.c b/tests/libgit2/pack/indexer.c
index 2ac287255..9722decaf 100644
--- a/tests/libgit2/pack/indexer.c
+++ b/tests/libgit2/pack/indexer.c
@@ -100,7 +100,12 @@ void test_pack_indexer__out_of_order(void)
git_indexer *idx = 0;
git_indexer_progress stats = { 0 };
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL));
+#endif
+
cl_git_pass(git_indexer_append(
idx, out_of_order_pack, out_of_order_pack_len, &stats));
cl_git_pass(git_indexer_commit(idx, &stats));
@@ -117,7 +122,12 @@ void test_pack_indexer__missing_trailer(void)
git_indexer *idx = 0;
git_indexer_progress stats = { 0 };
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL));
+#endif
+
cl_git_pass(git_indexer_append(
idx, missing_trailer_pack, missing_trailer_pack_len, &stats));
cl_git_fail(git_indexer_commit(idx, &stats));
@@ -133,7 +143,12 @@ void test_pack_indexer__leaky(void)
git_indexer *idx = 0;
git_indexer_progress stats = { 0 };
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL));
+#endif
+
cl_git_pass(git_indexer_append(
idx, leaky_pack, leaky_pack_len, &stats));
cl_git_fail(git_indexer_commit(idx, &stats));
@@ -151,6 +166,7 @@ void test_pack_indexer__fix_thin(void)
git_repository *repo;
git_odb *odb;
git_oid id, should_id;
+ git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT;
cl_git_pass(git_repository_init(&repo, "thin.git", true));
cl_git_pass(git_repository_odb(&odb, repo));
@@ -160,7 +176,13 @@ void test_pack_indexer__fix_thin(void)
git_oid__fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18", GIT_OID_SHA1);
cl_assert_equal_oid(&should_id, &id);
- cl_git_pass(git_indexer_new(&idx, ".", 0, odb, NULL));
+#ifdef GIT_EXPERIMENTAL_SHA256
+ opts.odb = odb;
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, &opts));
+#else
+ cl_git_pass(git_indexer_new(&idx, ".", 0, odb, &opts));
+#endif
+
cl_git_pass(git_indexer_append(idx, thin_pack, thin_pack_len, &stats));
cl_git_pass(git_indexer_commit(idx, &stats));
@@ -192,7 +214,12 @@ void test_pack_indexer__fix_thin(void)
cl_git_pass(p_stat(name, &st));
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL));
+#endif
+
read = p_read(fd, buffer, sizeof(buffer));
cl_assert(read != -1);
p_close(fd);
@@ -216,6 +243,7 @@ void test_pack_indexer__corrupt_length(void)
git_repository *repo;
git_odb *odb;
git_oid id, should_id;
+ git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT;
cl_git_pass(git_repository_init(&repo, "thin.git", true));
cl_git_pass(git_repository_odb(&odb, repo));
@@ -225,7 +253,13 @@ void test_pack_indexer__corrupt_length(void)
git_oid__fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18", GIT_OID_SHA1);
cl_assert_equal_oid(&should_id, &id);
- cl_git_pass(git_indexer_new(&idx, ".", 0, odb, NULL));
+#ifdef GIT_EXPERIMENTAL_SHA256
+ opts.odb = odb;
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, &opts));
+#else
+ cl_git_pass(git_indexer_new(&idx, ".", 0, odb, &opts));
+#endif
+
cl_git_pass(git_indexer_append(
idx, corrupt_thin_pack, corrupt_thin_pack_len, &stats));
cl_git_fail(git_indexer_commit(idx, &stats));
@@ -246,7 +280,12 @@ void test_pack_indexer__incomplete_pack_fails_with_strict(void)
opts.verify = 1;
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, &opts));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, &opts));
+#endif
+
cl_git_pass(git_indexer_append(
idx, incomplete_pack, incomplete_pack_len, &stats));
cl_git_fail(git_indexer_commit(idx, &stats));
@@ -266,7 +305,12 @@ void test_pack_indexer__out_of_order_with_connectivity_checks(void)
opts.verify = 1;
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, &opts));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, &opts));
+#endif
+
cl_git_pass(git_indexer_append(
idx, out_of_order_pack, out_of_order_pack_len, &stats));
cl_git_pass(git_indexer_commit(idx, &stats));
@@ -309,7 +353,12 @@ void test_pack_indexer__no_tmp_files(void)
git_str_dispose(&path);
cl_assert(git_str_len(&first_tmp_file) == 0);
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL));
+#endif
+
git_indexer_free(idx);
cl_git_pass(git_str_sets(&path, clar_sandbox_path()));
diff --git a/tests/libgit2/pack/packbuilder.c b/tests/libgit2/pack/packbuilder.c
index 0889f46ed..ff3dc1f68 100644
--- a/tests/libgit2/pack/packbuilder.c
+++ b/tests/libgit2/pack/packbuilder.c
@@ -104,7 +104,12 @@ void test_pack_packbuilder__create_pack(void)
seed_packbuilder();
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&_indexer, ".", GIT_OID_SHA1, NULL));
+#else
cl_git_pass(git_indexer_new(&_indexer, ".", 0, NULL, NULL));
+#endif
+
cl_git_pass(git_packbuilder_foreach(_packbuilder, feed_indexer, &stats));
cl_git_pass(git_indexer_commit(_indexer, &stats));
@@ -244,7 +249,13 @@ void test_pack_packbuilder__foreach(void)
git_indexer *idx;
seed_packbuilder();
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL));
+#endif
+
cl_git_pass(git_packbuilder_foreach(_packbuilder, foreach_cb, idx));
cl_git_pass(git_indexer_commit(idx, &_stats));
git_indexer_free(idx);
@@ -262,7 +273,13 @@ void test_pack_packbuilder__foreach_with_cancel(void)
git_indexer *idx;
seed_packbuilder();
+
+#ifdef GIT_EXPERIMENTAL_SHA256
+ cl_git_pass(git_indexer_new(&idx, ".", GIT_OID_SHA1, NULL));
+#else
cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL));
+#endif
+
cl_git_fail_with(
git_packbuilder_foreach(_packbuilder, foreach_cancel_cb, idx), -1111);
git_indexer_free(idx);