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( ...@@ -640,7 +640,7 @@ int git_odb_exists_prefix(
{ {
int error = GIT_ENOTFOUND, num_found = 0; int error = GIT_ENOTFOUND, num_found = 0;
size_t i; size_t i;
git_oid last_found = {{0}}, found; git_oid key = {{0}}, last_found = {{0}}, found;
assert(db && short_id); assert(db && short_id);
...@@ -659,6 +659,11 @@ int git_odb_exists_prefix( ...@@ -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) { for (i = 0; i < db->backends.length; ++i) {
backend_internal *internal = git_vector_get(&db->backends, i); backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend; git_odb_backend *b = internal->backend;
...@@ -666,7 +671,7 @@ int git_odb_exists_prefix( ...@@ -666,7 +671,7 @@ int git_odb_exists_prefix(
if (!b->exists_prefix) if (!b->exists_prefix)
continue; 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) if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
continue; continue;
if (error) if (error)
...@@ -683,11 +688,11 @@ int git_odb_exists_prefix( ...@@ -683,11 +688,11 @@ int git_odb_exists_prefix(
} }
if (!num_found) 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) if (out)
git_oid_cpy(out, &last_found); 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) 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( ...@@ -790,7 +795,7 @@ int git_odb_read_prefix(
{ {
size_t i; size_t i;
int error = GIT_ENOTFOUND; int error = GIT_ENOTFOUND;
git_oid found_full_oid = {{0}}; git_oid key = {{0}}, found_full_oid = {{0}};
git_rawobj raw; git_rawobj raw;
void *data = NULL; void *data = NULL;
bool found = false; bool found = false;
...@@ -809,13 +814,18 @@ int git_odb_read_prefix( ...@@ -809,13 +814,18 @@ int git_odb_read_prefix(
return 0; 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) { for (i = 0; i < db->backends.length; ++i) {
backend_internal *internal = git_vector_get(&db->backends, i); backend_internal *internal = git_vector_get(&db->backends, i);
git_odb_backend *b = internal->backend; git_odb_backend *b = internal->backend;
if (b->read_prefix != NULL) { if (b->read_prefix != NULL) {
git_oid full_oid; 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) if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
continue; continue;
...@@ -836,7 +846,7 @@ int git_odb_read_prefix( ...@@ -836,7 +846,7 @@ int git_odb_read_prefix(
} }
if (!found) 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) if ((object = odb_object__alloc(&found_full_oid, &raw)) == NULL)
return -1; return -1;
......
...@@ -26,6 +26,13 @@ void test_object_shortid__select(void) ...@@ -26,6 +26,13 @@ void test_object_shortid__select(void)
cl_assert_equal_s("ce01362", shorty.ptr); cl_assert_equal_s("ce01362", shorty.ptr);
git_object_free(obj); 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"); git_oid_fromstr(&full, "dea509d097ce692e167dfc6a48a7a280cc5e877e");
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY)); cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
cl_git_pass(git_object_short_id(&shorty, obj)); cl_git_pass(git_object_short_id(&shorty, obj));
......
...@@ -66,23 +66,25 @@ void test_odb_loose__cleanup(void) ...@@ -66,23 +66,25 @@ void test_odb_loose__cleanup(void)
void test_odb_loose__exists(void) void test_odb_loose__exists(void)
{ {
git_oid id, id2; git_oid id, id2;
git_odb *odb; git_odb *odb;
write_object_files(&one); write_object_files(&one);
cl_git_pass(git_odb_open(&odb, "test-objects")); 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)); /* Test for a missing object */
cl_assert(git_oid_equal(&id, &id2)); 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_fromstrp(&id, "8b13789a"));
cl_git_pass(git_oid_fromstr(&id2, "8b137891791fe96927ad78e64b0aad7bded08baa")); cl_assert_equal_i(GIT_ENOTFOUND, git_odb_exists_prefix(&id2, odb, &id, 8));
cl_assert(!git_odb_exists(odb, &id2));
cl_assert_equal_i(GIT_ENOTFOUND, git_odb_exists_prefix(NULL, odb, &id2, 8));
git_odb_free(odb); 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