Commit 282283acc65bab9de231a2b3dc489eb171d5f1cf

Russell Belfer 2012-05-04T16:46:46

Fix valgrind issues There are three changes here: - correctly propogate error code from failed object lookups - make zlib inflate use our allocators - add OID to notfound error in ODB lookups

diff --git a/src/object.c b/src/object.c
index 7189d60..e02bd69 100644
--- a/src/object.c
+++ b/src/object.c
@@ -146,7 +146,7 @@ int git_object_lookup_prefix(
 	}
 
 	if (error < 0)
-		return -1;
+		return error;
 
 	if (type != GIT_OBJ_ANY && type != odb_obj->raw.type) {
 		git_odb_object_free(odb_obj);
diff --git a/src/odb.c b/src/odb.c
index 2538b8a..934b317 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -589,7 +589,7 @@ int git_odb_read_prefix(
 	}
 
 	if (found == 0)
-		return git_odb__error_notfound("no match for prefix");
+		return git_odb__error_notfound("no match for prefix", short_id);
 	if (found > 1)
 		return git_odb__error_ambiguous("multiple matches for prefix");
 
@@ -684,9 +684,15 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi
 	return error;
 }
 
-int git_odb__error_notfound(const char *message)
+int git_odb__error_notfound(const char *message, const git_oid *oid)
 {
-	giterr_set(GITERR_ODB, "Object not found - %s", message);
+	if (oid != NULL) {
+		char oid_str[GIT_OID_HEXSZ + 1];
+		git_oid_tostr(oid_str, sizeof(oid_str), oid);
+		giterr_set(GITERR_ODB, "Object not found - %s (%s)", message, oid_str);
+	} else
+		giterr_set(GITERR_ODB, "Object not found - %s", message);
+
 	return GIT_ENOTFOUND;
 }
 
diff --git a/src/odb.h b/src/odb.h
index 4c425c0..263e4c3 100644
--- a/src/odb.h
+++ b/src/odb.h
@@ -70,7 +70,7 @@ int git_odb__hashlink(git_oid *out, const char *path);
 /*
  * Generate a GIT_ENOTFOUND error for the ODB.
  */
-int git_odb__error_notfound(const char *message);
+int git_odb__error_notfound(const char *message, const git_oid *oid);
 
 /*
  * Generate a GIT_EAMBIGUOUS error for the ODB.
diff --git a/src/odb_loose.c b/src/odb_loose.c
index d028dec..989b03a 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -528,7 +528,7 @@ static int locate_object_short_oid(
 
 	/* Check that directory exists */
 	if (git_path_isdir(object_location->ptr) == false)
-		return git_odb__error_notfound("failed to locate from short oid");
+		return git_odb__error_notfound("no matching loose object for prefix", short_oid);
 
 	state.dir_len = git_buf_len(object_location);
 	state.short_oid_len = len;
@@ -541,7 +541,7 @@ static int locate_object_short_oid(
 		return error;
 
 	if (!state.found)
-		return git_odb__error_notfound("failed to locate from short oid");
+		return git_odb__error_notfound("no matching loose object for prefix", short_oid);
 
 	/* Convert obtained hex formatted oid to raw */
 	error = git_oid_fromstr(res_oid, (char *)state.res_oid);
@@ -590,7 +590,7 @@ static int loose_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_
 	raw.type = GIT_OBJ_BAD;
 
 	if (locate_object(&object_path, (loose_backend *)backend, oid) < 0)
-		error = git_odb__error_notfound("in loose backend");
+		error = git_odb__error_notfound("no matching loose object", oid);
 	else if ((error = read_header_loose(&raw, &object_path)) == 0) {
 		*len_p = raw.len;
 		*type_p = raw.type;
@@ -610,7 +610,7 @@ static int loose_backend__read(void **buffer_p, size_t *len_p, git_otype *type_p
 	assert(backend && oid);
 
 	if (locate_object(&object_path, (loose_backend *)backend, oid) < 0)
-		error = git_odb__error_notfound("in loose backend");
+		error = git_odb__error_notfound("no matching loose object", oid);
 	else if ((error = read_loose(&raw, &object_path)) == 0) {
 		*buffer_p = raw.data;
 		*len_p = raw.len;
diff --git a/src/odb_pack.c b/src/odb_pack.c
index 242200b..458f288 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -242,7 +242,7 @@ static int packfile_refresh_all(struct pack_backend *backend)
 		return 0;
 
 	if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode))
-		return git_odb__error_notfound("failed to refresh packfiles");
+		return git_odb__error_notfound("failed to refresh packfiles", NULL);
 
 	if (st.st_mtime != backend->pack_folder_mtime) {
 		git_buf path = GIT_BUF_INIT;
@@ -288,7 +288,7 @@ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backen
 		}
 	}
 
-	return git_odb__error_notfound("failed to find pack entry");
+	return git_odb__error_notfound("failed to find pack entry", oid);
 }
 
 static int pack_entry_find_prefix(
@@ -330,7 +330,7 @@ static int pack_entry_find_prefix(
 	}
 
 	if (!found)
-		return git_odb__error_notfound("failed to find pack entry");
+		return git_odb__error_notfound("no matching pack entry for prefix", short_oid);
 	else if (found > 1)
 		return git_odb__error_ambiguous("found multiple pack entries");
 	else
diff --git a/src/pack.c b/src/pack.c
index 8d71138..4a6bc6a 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -375,6 +375,18 @@ int git_packfile_unpack(
 	return error;
 }
 
+static void *use_git_alloc(void *opaq, unsigned int count, unsigned int size)
+{
+	GIT_UNUSED(opaq);
+	return git__calloc(count, size);
+}
+
+static void use_git_free(void *opaq, void *ptr)
+{
+	GIT_UNUSED(opaq);
+	git__free(ptr);
+}
+
 int packfile_unpack_compressed(
 	git_rawobj *obj,
 	struct git_pack_file *p,
@@ -393,6 +405,8 @@ int packfile_unpack_compressed(
 	memset(&stream, 0, sizeof(stream));
 	stream.next_out = buffer;
 	stream.avail_out = (uInt)size + 1;
+	stream.zalloc = use_git_alloc;
+	stream.zfree = use_git_free;
 
 	st = inflateInit(&stream);
 	if (st != Z_OK) {
@@ -541,7 +555,7 @@ static int packfile_open(struct git_pack_file *p)
 	assert(p->index_map.data);
 
 	if (!p->index_map.data && pack_index_open(p) < 0)
-		return git_odb__error_notfound("failed to open packfile");
+		return git_odb__error_notfound("failed to open packfile", NULL);
 
 	/* TODO: open with noatime */
 	p->mwf.fd = git_futils_open_ro(p->pack_name);
@@ -615,7 +629,7 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path)
 	path_len -= strlen(".idx");
 	if (path_len < 1) {
 		git__free(p);
-		return git_odb__error_notfound("invalid packfile path");
+		return git_odb__error_notfound("invalid packfile path", NULL);
 	}
 
 	memcpy(p->pack_name, path, path_len);
@@ -627,7 +641,7 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path)
 	strcpy(p->pack_name + path_len, ".pack");
 	if (p_stat(p->pack_name, &st) < 0 || !S_ISREG(st.st_mode)) {
 		git__free(p);
-		return git_odb__error_notfound("packfile not found");
+		return git_odb__error_notfound("packfile not found", NULL);
 	}
 
 	/* ok, it looks sane as far as we can check without
@@ -733,9 +747,8 @@ static int pack_entry_find_offset(
 		if (pos < (int)p->num_objects) {
 			current = index + pos * stride;
 
-			if (!git_oid_ncmp(short_oid, (const git_oid *)current, len)) {
+			if (!git_oid_ncmp(short_oid, (const git_oid *)current, len))
 				found = 1;
-			}
 		}
 	}
 
@@ -749,7 +762,7 @@ static int pack_entry_find_offset(
 	}
 
 	if (!found)
-		return git_odb__error_notfound("failed to find offset for pack entry");
+		return git_odb__error_notfound("failed to find offset for pack entry", short_oid);
 	if (found > 1)
 		return git_odb__error_ambiguous("found multiple offsets for pack entry");
 	*offset_out = nth_packed_object_offset(p, pos);