Commit Diff


commit - d4eec7d5a4198505ab2a13e256444d57033846b9
commit + 2d9874c22b16a541dd8300cf257123c5aaf88e5e
blob - eec49fff02579b61fd3d35f81f6eb23e587eaa85
blob + 200912c713739f0decd93dec31328867fafb67b2
--- include/got_object.h
+++ include/got_object.h
@@ -15,7 +15,7 @@
  */
 
 #define GOT_OBJECT_ID_MAXLEN SHA256_DIGEST_LENGTH
-#define GOT_OBJECT_ID_HEX_MAXLEN SHA1_DIGEST_STRING_LENGTH
+#define GOT_OBJECT_ID_HEX_MAXLEN SHA256_DIGEST_STRING_LENGTH
 
 enum got_hash_algorithm {
 	GOT_HASH_SHA1,
@@ -23,7 +23,8 @@ enum got_hash_algorithm {
 };
 
 struct got_object_id {
-	u_int8_t hash[SHA1_DIGEST_LENGTH];
+	u_int8_t hash[GOT_OBJECT_ID_MAXLEN];
+	enum got_hash_algorithm algo;
 };
 
 struct got_blob_object;
@@ -367,7 +368,7 @@ const char *got_object_tag_get_tagger(struct got_tag_o
 const char *got_object_tag_get_message(struct got_tag_object *);
 
 const struct got_error *got_object_commit_add_parent(struct got_commit_object *,
-    const char *);
+    const char *, enum got_hash_algorithm);
 
 /* Create a new tag object in the repository. */
 const struct got_error *got_object_tag_create(struct got_object_id **,
blob - 1fe139974d76af32b2f41b225e9552489ebf6e6c
blob + 4b8bd0c0d5c2c12b0e4966d7d1dfe9ee4bbdea51
--- lib/got_lib_object_parse.h
+++ lib/got_lib_object_parse.h
@@ -37,6 +37,8 @@ struct got_parsed_tree_entry {
 	size_t namelen; /* strlen(name) */
 	mode_t mode; /* Mode parsed from tree buffer. */
 	uint8_t *id; /* Points to ID in parsed tree buffer. */
+	size_t idlen;
+	int algo;
 };
 const struct got_error *got_object_parse_tree(struct got_parsed_tree_entry **,
     size_t *, size_t *, uint8_t *, size_t, enum got_hash_algorithm);
blob - 013a402d0c1fab8136006cdfa4f5a916f5c02608
blob + 311ed83f2360a0ab6467b0bff815b90ed66af55c
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -257,7 +257,8 @@ struct got_imsg_commit_object {
 } __attribute__((__packed__));
 
 struct got_imsg_tree_entry {
-	char id[SHA1_DIGEST_LENGTH];
+	char id[GOT_OBJECT_ID_MAXLEN];
+	int algo;
 	mode_t mode;
 	size_t namelen;
 	/* Followed by namelen bytes of entry's name, not NUL-terminated. */
blob - 6ce635e299cfb8a3b1d2cc29df47893282d7e9e6
blob + 8a9aead4a18206bce1d17c6c29f680f879b9fd30
--- lib/object.c
+++ lib/object.c
@@ -151,7 +151,9 @@ got_object_open_by_id_str(struct got_object **obj, str
 {
 	struct got_object_id id;
 
-	if (!got_parse_sha1_digest(id.hash, id_str))
+	memset(&id, 0, sizeof(id));
+	id.algo = got_repo_get_object_format(repo);
+	if (!got_parse_hash_digest(id.hash, id_str, id.algo))
 		return got_error_path(id_str, GOT_ERR_BAD_OBJ_ID_STR);
 
 	return got_object_open(obj, repo, &id);
blob - f97fe014b8a77fe7922a580d07e131817cf8074d
blob + f12227a87fbf29ca50b94510c24cd6e56bb0c966
--- lib/object_parse.c
+++ lib/object_parse.c
@@ -72,7 +72,14 @@ int
 got_object_id_cmp(const struct got_object_id *id1,
     const struct got_object_id *id2)
 {
-	return memcmp(id1->hash, id2->hash, SHA1_DIGEST_LENGTH);
+	if (id1->algo != id2->algo)
+		abort(); // return -1;
+	if (id1->algo == GOT_HASH_SHA1)
+		return memcmp(id1->hash, id2->hash, SHA1_DIGEST_LENGTH);
+	if (id1->algo == GOT_HASH_SHA256)
+		return memcmp(id1->hash, id2->hash, SHA256_DIGEST_LENGTH);
+	abort();
+	return -1;
 }
 
 const struct got_error *
@@ -107,7 +114,7 @@ got_object_id_str(char **outbuf, struct got_object_id 
 char *
 got_object_id_hex(struct got_object_id *id, char *buf, size_t len)
 {
-	return got_sha1_digest_to_str(id->hash, buf, len);
+	return got_hash_digest_to_str(id->hash, buf, len, id->algo);
 }
 
 void
@@ -299,7 +306,7 @@ got_object_read_raw(uint8_t **outbuf, off_t *size, siz
 	*size = 0;
 	*hdrlen = 0;
 
-	got_hash_init(&ctx, GOT_HASH_SHA1);
+	got_hash_init(&ctx, expected_id->algo);
 	memset(&csum, 0, sizeof(csum));
 	csum.output_ctx = &ctx;
 
@@ -378,7 +385,7 @@ got_object_commit_alloc_partial(void)
 
 const struct got_error *
 got_object_commit_add_parent(struct got_commit_object *commit,
-    const char *id_str)
+    const char *id_str, enum got_hash_algorithm algo)
 {
 	const struct got_error *err = NULL;
 	struct got_object_qid *qid;
@@ -387,7 +394,8 @@ got_object_commit_add_parent(struct got_commit_object 
 	if (err)
 		return err;
 
-	if (!got_parse_sha1_digest(qid->id.hash, id_str)) {
+	qid->id.algo = algo;
+	if (!got_parse_hash_digest(qid->id.hash, id_str, algo)) {
 		err = got_error(GOT_ERR_BAD_OBJ_DATA);
 		got_object_qid_free(qid);
 		return err;
@@ -645,6 +653,7 @@ got_object_parse_commit(struct got_commit_object **com
 			err = got_error(GOT_ERR_BAD_OBJ_DATA);
 			goto done;
 		}
+		(*commit)->tree_id->algo = algo;
 		remain -= idlen;
 		s += idlen;
 	} else {
@@ -660,7 +669,7 @@ got_object_parse_commit(struct got_commit_object **com
 			goto done;
 		}
 		s += label_len;
-		err = got_object_commit_add_parent(*commit, s);
+		err = got_object_commit_add_parent(*commit, s, algo);
 		if (err)
 			goto done;
 
@@ -755,7 +764,10 @@ got_object_read_commit(struct got_commit_object **comm
 	struct got_hash ctx;
 	struct got_object_id id;
 
-	got_hash_init(&ctx, GOT_HASH_SHA1);
+	memset(&id, 0, sizeof(id));
+	id.algo = expected_id->algo;
+
+	got_hash_init(&ctx, expected_id->algo);
 	memset(&csum, 0, sizeof(csum));
 	csum.output_ctx = &ctx;
 
@@ -786,7 +798,7 @@ got_object_read_commit(struct got_commit_object **comm
 	/* Skip object header. */
 	len -= obj->hdrlen;
 	err = got_object_parse_commit(commit, p + obj->hdrlen, len,
-	    GOT_HASH_SHA1);
+	    expected_id->algo);
 done:
 	free(p);
 	if (obj)
@@ -809,7 +821,7 @@ got_object_tree_close(struct got_tree_object *tree)
 
 static const struct got_error *
 parse_tree_entry(struct got_parsed_tree_entry *pte, size_t *elen, char *buf,
-    size_t maxlen, size_t idlen)
+    size_t maxlen, enum got_hash_algorithm algo, size_t idlen)
 {
 	char *p, *space;
 
@@ -840,7 +852,8 @@ parse_tree_entry(struct got_parsed_tree_entry *pte, si
 	pte->namelen = strlen(pte->name);
 	buf += *elen;
 	pte->id = buf;
-	// pte->idlen = idlen;
+	pte->idlen = idlen;
+	pte->algo = algo;
 	*elen += idlen;
 	return NULL;
 }
@@ -859,11 +872,13 @@ got_object_parse_tree(struct got_parsed_tree_entry **e
     enum got_hash_algorithm algo)
 {
 	const struct got_error *err = NULL;
-	size_t remain = len;
+	size_t idlen, remain = len;
 	const size_t nalloc = 16;
 	struct got_parsed_tree_entry *pte;
 	int i;
 
+	idlen = got_hash_digest_length(algo);
+
 	*nentries = 0;
 	if (remain == 0)
 		return NULL; /* tree is empty */
@@ -883,8 +898,7 @@ got_object_parse_tree(struct got_parsed_tree_entry **e
 		}
 
 		pte = &(*entries)[*nentries];
-		err = parse_tree_entry(pte, &elen, buf, remain,
-		    got_hash_digest_length(algo));
+		err = parse_tree_entry(pte, &elen, buf, remain, algo, idlen);
 		if (err)
 			goto done;
 		buf += elen;
@@ -928,7 +942,10 @@ got_object_read_tree(struct got_parsed_tree_entry **en
 	struct got_hash ctx;
 	struct got_object_id id;
 
-	got_hash_init(&ctx, GOT_HASH_SHA1);
+	memset(&id, 0, sizeof(id));
+	id.algo = expected_id->algo;
+
+	got_hash_init(&ctx, expected_id->algo);
 	memset(&csum, 0, sizeof(csum));
 	csum.output_ctx = &ctx;
 
@@ -954,7 +971,7 @@ got_object_read_tree(struct got_parsed_tree_entry **en
 	/* Skip object header. */
 	len -= obj->hdrlen;
 	err = got_object_parse_tree(entries, nentries, nentries_alloc,
-	    *p + obj->hdrlen, len, GOT_HASH_SHA1);
+	    *p + obj->hdrlen, len, expected_id->algo);
 done:
 	if (obj)
 		got_object_close(obj);
@@ -1006,6 +1023,7 @@ got_object_parse_tag(struct got_tag_object **tag, uint
 			err = got_error(GOT_ERR_BAD_OBJ_DATA);
 			goto done;
 		}
+		(*tag)->id.algo = algo;
 		remain -= id_len;
 		s += id_len;
 	} else {
@@ -1170,7 +1188,10 @@ got_object_read_tag(struct got_tag_object **tag, int f
 	struct got_hash ctx;
 	struct got_object_id id;
 
-	got_hash_init(&ctx, GOT_HASH_SHA1);
+	memset(&id, 0, sizeof(id));
+	id.algo = expected_id->algo;
+
+	got_hash_init(&ctx, expected_id->algo);
 	memset(&csum, 0, sizeof(csum));
 	csum.output_ctx = &ctx;
 
@@ -1197,7 +1218,7 @@ got_object_read_tag(struct got_tag_object **tag, int f
 	/* Skip object header. */
 	len -= obj->hdrlen;
 	err = got_object_parse_tag(tag, p + obj->hdrlen, len,
-	    GOT_HASH_SHA1);
+	    expected_id->algo);
 done:
 	free(p);
 	if (obj)
blob - 8f9592941a48ee995d730c7c932ebc6ea4a4f574
blob + fad24a1058351eb3d8093ed6c825dea578d07d18
--- lib/pack.c
+++ lib/pack.c
@@ -445,8 +445,8 @@ got_packidx_close(struct got_packidx *packidx)
 	return err;
 }
 
-const struct got_error *
-got_packidx_get_packfile_path(char **path_packfile, const char *path_packidx)
+static const struct got_error *
+packfile_path(char **path_packfile, const char *path_packidx)
 {
 	size_t size;
 
@@ -470,6 +470,19 @@ got_packidx_get_packfile_path(char **path_packfile, co
 	return NULL;
 }
 
+const struct got_error *
+got_packidx_get_packfile_path(char **path_packfile, const char *path)
+{
+	const struct got_error *err;
+
+	err = packfile_path(path_packfile, path);
+	if (err) {
+		fprintf(stderr, "%s: failed for path %s: %s\n",
+		    __func__, path, err->msg);
+	}
+	return err;
+}
+
 off_t
 got_packidx_get_object_offset(struct got_packidx *packidx, int idx)
 {
blob - 7f15bf37fe4ec0704fd41e0612b9c21663dc29d6
blob + 4ea3be08309929c3ea1c63fe2e2331de3224a8a2
--- lib/privsep.c
+++ lib/privsep.c
@@ -1421,11 +1421,17 @@ send_tree_entries_batch(struct imsgbuf *ibuf,
 		return got_error_from_errno("imsg_add TREE_ENTRY");
 
 	for (i = idx0; i <= idxN; i++) {
+		static const char gap[12]; /* for sha1 inside sha256 align. */
 		struct got_parsed_tree_entry *pte = &entries[i];
 
 		/* Keep in sync with struct got_imsg_tree_entry definition! */
-		if (imsg_add(wbuf, pte->id, SHA1_DIGEST_LENGTH) == -1)
+		if (imsg_add(wbuf, pte->id, pte->idlen) == -1)
+			return got_error_from_errno("imsg_add TREE_ENTRY");
+		if (pte->idlen != SHA256_DIGEST_LENGTH &&
+		    imsg_add(wbuf, gap, sizeof(gap)) == -1)
 			return got_error_from_errno("imsg_add TREE_ENTRY");
+		if (imsg_add(wbuf, &pte->algo, sizeof(pte->algo)) == -1)
+			return got_error_from_errno("imsg_add TREE_ENTRY");
 		if (imsg_add(wbuf, &pte->mode, sizeof(pte->mode)) == -1)
 			return got_error_from_errno("imsg_add TREE_ENTRY");
 		if (imsg_add(wbuf, &pte->namelen, sizeof(pte->namelen)) == -1)
@@ -1452,8 +1458,8 @@ send_tree_entries(struct imsgbuf *ibuf, struct got_par
 	i = 0;
 	for (j = 0; j < nentries; j++) {
 		struct got_parsed_tree_entry *pte = &entries[j];
-		size_t len = SHA1_DIGEST_LENGTH + sizeof(pte->mode) +
-		    sizeof(pte->namelen) + pte->namelen;
+		size_t len = sizeof(struct got_imsg_tree_entry)
+		    + pte->namelen;
 
 		if (j > 0 &&
 		    entries_len + len > MAX_IMSGSIZE - IMSG_HEADER_SIZE) {
@@ -1550,7 +1556,8 @@ recv_tree_entries(void *data, size_t datalen, struct g
 		te_name = buf + sizeof(ite);
 		memcpy(te->name, te_name, ite.namelen);
 		te->name[ite.namelen] = '\0';
-		memcpy(te->id.hash, ite.id, SHA1_DIGEST_LENGTH);
+		memcpy(te->id.hash, ite.id, got_hash_digest_length(ite.algo));
+		te->id.algo = ite.algo;
 		te->mode = ite.mode;
 		te->idx = *nentries;
 		(*nentries)++;
blob - 153649083be68fbacb30ebb82575b58f1020bc81
blob + 964dae0fb465818b184169f4311aa6ad3662d86e
--- lib/reference.c
+++ lib/reference.c
@@ -162,6 +162,8 @@ parse_ref_line(struct got_reference **ref, const char 
 		return parse_symref(ref, name, line);
 	}
 
+	memset(&id, 0, sizeof(id));
+	id.algo = algo;
 	if (!got_parse_hash_digest(id.hash, line, algo))
 		return got_error(GOT_ERR_BAD_REF_DATA);
 
@@ -301,6 +303,8 @@ parse_packed_ref_line(struct got_reference **ref, cons
 	if (line[0] == '#' || line[0] == '^')
 		return NULL;
 
+	memset(&id, 0, sizeof(id));
+	id.algo = algo;
 	if (!got_parse_hash_digest(id.hash, line, algo))
 		return got_error(GOT_ERR_BAD_REF_DATA);
 
@@ -591,6 +595,7 @@ ref_resolve(struct got_object_id **id, struct got_repo
 	if (*id == NULL)
 		return got_error_from_errno("calloc");
 	memcpy(*id, &ref->ref.ref.id, sizeof(**id));
+
 	return NULL;
 }
 
blob - 4e019bb51759120b39ec4c08a477f9e58b998a4b
blob + b91b6d154554c6405825c3c00d9f73af2fab6126
--- lib/repository.c
+++ lib/repository.c
@@ -1123,7 +1123,8 @@ got_repo_check_packidx_bloom_filter(struct got_reposit
 
 	bf = get_packidx_bloom_filter(repo, path_packidx, strlen(path_packidx));
 	if (bf)
-		return bloom_check(bf->bloom, id->hash, sizeof(id->hash));
+		return bloom_check(bf->bloom, id->hash,
+		    got_hash_digest_length(id->algo));
 
 	/* No bloom filter means this pack index must be searched. */
 	return 1;
blob - 91c4b3a6886513f019c967bee323d90699e8d6fb
blob + 749d0f2666d9c5e80bb3d20f09fa8d4d2368943c
--- libexec/got-read-blob/got-read-blob.c
+++ libexec/got-read-blob/got-read-blob.c
@@ -80,10 +80,6 @@ main(int argc, char *argv[])
 		struct got_inflate_checksum csum;
 		struct got_hash ctx;
 
-		got_hash_init(&ctx, GOT_HASH_SHA1);
-		memset(&csum, 0, sizeof(csum));
-		csum.output_ctx = &ctx;
-
 		memset(&imsg, 0, sizeof(imsg));
 		imsg.fd = -1;
 		memset(&imsg_outfd, 0, sizeof(imsg_outfd));
@@ -161,6 +157,13 @@ main(int argc, char *argv[])
 			goto done;
 		}
 
+		memset(&id, 0, sizeof(id));
+		id.algo = expected_id.algo;
+
+		got_hash_init(&ctx, expected_id.algo);
+		memset(&csum, 0, sizeof(csum));
+		csum.output_ctx = &ctx;
+
 		if (obj->size + obj->hdrlen <=
 		    GOT_PRIVSEP_INLINE_BLOB_DATA_MAX) {
 			err = got_inflate_to_mem(&buf, &size, NULL, &csum, f);
blob - 588b4f006b33d0a701ce9f5a483d27b23295806c
blob + d3c13c2f14fc04f87f98c38edf0cbfbc5ef5705e
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
@@ -212,7 +212,7 @@ open_tree(uint8_t **buf, struct got_parsed_tree_entry 
 	obj->size = len;
 
 	err = got_object_parse_tree(entries, nentries, nentries_alloc,
-	    *buf, len, GOT_HASH_SHA1);
+	    *buf, len, id->algo);
 done:
 	got_object_close(obj);
 	if (err) {
@@ -411,7 +411,7 @@ tag_request(struct imsg *imsg, struct imsgbuf *ibuf, s
 		goto done;
 
 	obj->size = len;
-	err = got_object_parse_tag(&tag, buf, len, GOT_HASH_SHA1);
+	err = got_object_parse_tag(&tag, buf, len, id.algo);
 	if (err)
 		goto done;
 
@@ -1439,7 +1439,7 @@ enumeration_request(struct imsg *imsg, struct imsgbuf 
 				goto done;
 			obj->size = len;
 			err = got_object_parse_tag(&tag, buf, len,
-			    GOT_HASH_SHA1);
+			    qid->id.algo);
 			if (err) {
 				free(buf);
 				goto done;