Commit 3ab57816 by Edward Thomson

Merge pull request #2178 from libgit2/rb/fix-short-id

Fix git_odb_short_id and git_odb_exists_prefix bugs
parents fad04120 eb46fb2b
......@@ -640,7 +640,7 @@ int git_odb_exists_prefix(
{
int error = GIT_ENOTFOUND, num_found = 0;
size_t i;
git_oid last_found = {{0}}, found;
git_oid key = {{0}}, last_found = {{0}}, found;
assert(db && short_id);
......@@ -659,6 +659,11 @@ int git_odb_exists_prefix(
}
}
/* just copy valid part of short_id */
memcpy(&key.id, short_id->id, (len + 1) / 2);
if (len & 1)
key.id[len / 2] &= 0xF0;
for (i = 0; i < db->backends.length; ++i) {
backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend;
......@@ -666,7 +671,7 @@ int git_odb_exists_prefix(
if (!b->exists_prefix)
continue;
error = b->exists_prefix(&found, b, short_id, len);
error = b->exists_prefix(&found, b, &key, len);
if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
continue;
if (error)
......@@ -683,11 +688,11 @@ int git_odb_exists_prefix(
}
if (!num_found)
return git_odb__error_notfound("no match for id prefix", short_id);
return git_odb__error_notfound("no match for id prefix", &key);
if (out)
git_oid_cpy(out, &last_found);
return error;
return 0;
}
int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id)
......@@ -790,7 +795,7 @@ int git_odb_read_prefix(
{
size_t i;
int error = GIT_ENOTFOUND;
git_oid found_full_oid = {{0}};
git_oid key = {{0}}, found_full_oid = {{0}};
git_rawobj raw;
void *data = NULL;
bool found = false;
......@@ -809,13 +814,18 @@ int git_odb_read_prefix(
return 0;
}
/* just copy valid part of short_id */
memcpy(&key.id, short_id->id, (len + 1) / 2);
if (len & 1)
key.id[len / 2] &= 0xF0;
for (i = 0; i < db->backends.length; ++i) {
backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend;
if (b->read_prefix != NULL) {
git_oid full_oid;
error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, short_id, len);
error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, &key, len);
if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
continue;
......@@ -836,7 +846,7 @@ int git_odb_read_prefix(
}
if (!found)
return git_odb__error_notfound("no match for prefix", short_id);
return git_odb__error_notfound("no match for prefix", &key);
if ((object = odb_object__alloc(&found_full_oid, &raw)) == NULL)
return -1;
......
......@@ -26,6 +26,13 @@ void test_object_shortid__select(void)
cl_assert_equal_s("ce01362", shorty.ptr);
git_object_free(obj);
git_oid_fromstr(&full, "038d718da6a1ebbc6a7780a96ed75a70cc2ad6e2");
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
cl_git_pass(git_object_short_id(&shorty, obj));
cl_assert_equal_i(7, shorty.size);
cl_assert_equal_s("038d718", shorty.ptr);
git_object_free(obj);
git_oid_fromstr(&full, "dea509d097ce692e167dfc6a48a7a280cc5e877e");
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
cl_git_pass(git_object_short_id(&shorty, obj));
......
......@@ -66,23 +66,25 @@ void test_odb_loose__cleanup(void)
void test_odb_loose__exists(void)
{
git_oid id, id2;
git_oid id, id2;
git_odb *odb;
write_object_files(&one);
write_object_files(&one);
cl_git_pass(git_odb_open(&odb, "test-objects"));
cl_git_pass(git_oid_fromstr(&id, one.id));
cl_git_pass(git_oid_fromstr(&id, one.id));
cl_assert(git_odb_exists(odb, &id));
cl_assert(git_odb_exists(odb, &id));
cl_git_pass(git_oid_fromstrp(&id, "8b137891"));
cl_git_pass(git_odb_exists_prefix(&id2, odb, &id, 8));
cl_assert_equal_i(0, git_oid_streq(&id2, one.id));
cl_assert(git_odb_exists_prefix(&id2, odb, &id, 8));
cl_assert(git_oid_equal(&id, &id2));
/* Test for a missing object */
cl_git_pass(git_oid_fromstr(&id, "8b137891791fe96927ad78e64b0aad7bded08baa"));
cl_assert(!git_odb_exists(odb, &id));
/* Test for a non-existant object */
cl_git_pass(git_oid_fromstr(&id2, "8b137891791fe96927ad78e64b0aad7bded08baa"));
cl_assert(!git_odb_exists(odb, &id2));
cl_assert_equal_i(GIT_ENOTFOUND, git_odb_exists_prefix(NULL, odb, &id2, 8));
cl_git_pass(git_oid_fromstrp(&id, "8b13789a"));
cl_assert_equal_i(GIT_ENOTFOUND, git_odb_exists_prefix(&id2, odb, &id, 8));
git_odb_free(odb);
}
......
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