Unverified Commit 895fd51a by Edward Thomson Committed by GitHub

Merge pull request #4474 from pks-t/pks/null-oid

Special-casing null OIDs
parents c935b926 275f103d
...@@ -53,6 +53,7 @@ static git_cache *odb_cache(git_odb *odb) ...@@ -53,6 +53,7 @@ static git_cache *odb_cache(git_odb *odb)
static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id); static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id);
static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth); static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth);
static int error_null_oid(int error, const char *message);
static git_otype odb_hardcoded_type(const git_oid *id) static git_otype odb_hardcoded_type(const git_oid *id)
{ {
...@@ -735,6 +736,9 @@ int git_odb_exists(git_odb *db, const git_oid *id) ...@@ -735,6 +736,9 @@ int git_odb_exists(git_odb *db, const git_oid *id)
assert(db && id); assert(db && id);
if (git_oid_iszero(id))
return 0;
if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) { if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
git_odb_object_free(object); git_odb_object_free(object);
return 1; return 1;
...@@ -958,6 +962,11 @@ int git_odb__read_header_or_object( ...@@ -958,6 +962,11 @@ int git_odb__read_header_or_object(
assert(db && id && out && len_p && type_p); assert(db && id && out && len_p && type_p);
*out = NULL;
if (git_oid_iszero(id))
return error_null_oid(GIT_ENOTFOUND, "cannot read object");
if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) { if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
*len_p = object->cached.size; *len_p = object->cached.size;
*type_p = object->cached.type; *type_p = object->cached.type;
...@@ -965,7 +974,6 @@ int git_odb__read_header_or_object( ...@@ -965,7 +974,6 @@ int git_odb__read_header_or_object(
return 0; return 0;
} }
*out = NULL;
error = odb_read_header_1(len_p, type_p, db, id, false); error = odb_read_header_1(len_p, type_p, db, id, false);
if (error == GIT_ENOTFOUND && !git_odb_refresh(db)) if (error == GIT_ENOTFOUND && !git_odb_refresh(db))
...@@ -1057,6 +1065,9 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id) ...@@ -1057,6 +1065,9 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
assert(out && db && id); assert(out && db && id);
if (git_oid_iszero(id))
return error_null_oid(GIT_ENOTFOUND, "cannot read object");
*out = git_cache_get_raw(odb_cache(db), id); *out = git_cache_get_raw(odb_cache(db), id);
if (*out != NULL) if (*out != NULL)
return 0; return 0;
...@@ -1078,6 +1089,9 @@ static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id) ...@@ -1078,6 +1089,9 @@ static int odb_otype_fast(git_otype *type_p, git_odb *db, const git_oid *id)
size_t _unused; size_t _unused;
int error; int error;
if (git_oid_iszero(id))
return error_null_oid(GIT_ENOTFOUND, "cannot get object type");
if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) { if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
*type_p = object->cached.type; *type_p = object->cached.type;
return 0; return 0;
...@@ -1231,6 +1245,10 @@ int git_odb_write( ...@@ -1231,6 +1245,10 @@ int git_odb_write(
assert(oid && db); assert(oid && db);
git_odb_hash(oid, data, len, type); git_odb_hash(oid, data, len, type);
if (git_oid_iszero(oid))
return error_null_oid(GIT_EINVALID, "cannot write object");
if (git_odb__freshen(db, oid)) if (git_odb__freshen(db, oid))
return 0; return 0;
...@@ -1484,6 +1502,12 @@ int git_odb__error_notfound( ...@@ -1484,6 +1502,12 @@ int git_odb__error_notfound(
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
} }
static int error_null_oid(int error, const char *message)
{
giterr_set(GITERR_ODB, "odb: %s: null OID cannot exist", message);
return error;
}
int git_odb__error_ambiguous(const char *message) int git_odb__error_ambiguous(const char *message)
{ {
giterr_set(GITERR_ODB, "ambiguous SHA1 prefix - %s", message); giterr_set(GITERR_ODB, "ambiguous SHA1 prefix - %s", message);
......
...@@ -498,6 +498,9 @@ static int append_entry( ...@@ -498,6 +498,9 @@ static int append_entry(
if (!valid_entry_name(bld->repo, filename)) if (!valid_entry_name(bld->repo, filename))
return tree_error("failed to insert entry: invalid name for a tree entry", filename); return tree_error("failed to insert entry: invalid name for a tree entry", filename);
if (git_oid_iszero(id))
return tree_error("failed to insert entry: invalid null OID for a tree entry", filename);
entry = alloc_entry(filename, strlen(filename), id); entry = alloc_entry(filename, strlen(filename), id);
GITERR_CHECK_ALLOC(entry); GITERR_CHECK_ALLOC(entry);
...@@ -740,6 +743,9 @@ int git_treebuilder_insert( ...@@ -740,6 +743,9 @@ int git_treebuilder_insert(
if (!valid_entry_name(bld->repo, filename)) if (!valid_entry_name(bld->repo, filename))
return tree_error("failed to insert entry: invalid name for a tree entry", filename); return tree_error("failed to insert entry: invalid name for a tree entry", filename);
if (git_oid_iszero(id))
return tree_error("failed to insert entry: invalid null OID", filename);
if (filemode != GIT_FILEMODE_COMMIT && if (filemode != GIT_FILEMODE_COMMIT &&
!git_object__is_valid(bld->repo, id, otype_from_mode(filemode))) !git_object__is_valid(bld->repo, id, otype_from_mode(filemode)))
return tree_error("failed to insert entry: invalid object specified", filename); return tree_error("failed to insert entry: invalid object specified", filename);
......
...@@ -512,3 +512,14 @@ void test_object_tree_write__object_validity(void) ...@@ -512,3 +512,14 @@ void test_object_tree_write__object_validity(void)
test_inserting_submodule(); test_inserting_submodule();
} }
void test_object_tree_write__invalid_null_oid(void)
{
git_treebuilder *bld;
git_oid null_oid = {{0}};
cl_git_pass(git_treebuilder_new(&bld, g_repo, NULL));
cl_git_fail(git_treebuilder_insert(NULL, bld, "null_oid_file", &null_oid, GIT_FILEMODE_BLOB));
cl_assert(giterr_last() && strstr(giterr_last()->message, "null OID") != NULL);
git_treebuilder_free(bld);
}
...@@ -230,3 +230,21 @@ void test_odb_backend_simple__exists_with_highly_ambiguous_prefix(void) ...@@ -230,3 +230,21 @@ void test_odb_backend_simple__exists_with_highly_ambiguous_prefix(void)
cl_git_pass(git_odb_exists_prefix(&found, _odb, &_oid, 40)); cl_git_pass(git_odb_exists_prefix(&found, _odb, &_oid, 40));
cl_assert(git_oid_equal(&found, &_oid)); cl_assert(git_oid_equal(&found, &_oid));
} }
void test_odb_backend_simple__null_oid_is_ignored(void)
{
const fake_object objs[] = {
{ "0000000000000000000000000000000000000000", "null oid content" },
{ NULL, NULL }
};
git_oid null_oid = {{0}};
git_odb_object *obj;
setup_backend(objs);
cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0));
cl_assert(!git_odb_exists(_odb, &null_oid));
cl_git_fail_with(GIT_ENOTFOUND, git_odb_read(&obj, _odb, &null_oid));
cl_assert(giterr_last() && strstr(giterr_last()->message, "null OID"));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment