Commit Diff


commit - be288a59f42e0b5e203e2c5545bf3e042ff4b79f
commit + c8ae092d079ca1c9f5f2a7e44c73948cd55454e7
blob - 6a161bc20df5aaa7789395593ab2ffc6fbe4b1fb
blob + 7672f9da04d627c9c0d625a0aeafe03183f72626
--- include/got_object.h
+++ include/got_object.h
@@ -16,6 +16,11 @@
 
 #define GOT_OBJECT_ID_HEX_MAXLEN SHA1_DIGEST_STRING_LENGTH
 
+enum got_hash_algorithm {
+	GOT_HASH_SHA1,
+	GOT_HASH_SHA256,
+};
+
 struct got_object_id {
 	u_int8_t sha1[SHA1_DIGEST_LENGTH];
 };
blob - 141cb2590fa14834c63381929a0a7438ae3e4556
blob + 6cf096112b33a6a0627c71d31836cc10bedb3469
--- lib/got_lib_hash.h
+++ lib/got_lib_hash.h
@@ -15,7 +15,13 @@
  */
 
 #define GOT_SHA1_STRING_ZERO "0000000000000000000000000000000000000000"
+#define GOT_SHA256_STRING_ZERO "0000000000000000000000000000000000000000000000000000000000000000"
 
 int got_parse_xdigit(uint8_t *, const char *);
-int got_parse_sha1_digest(uint8_t *, const char *);
+
 char *got_sha1_digest_to_str(const uint8_t *, char *, size_t);
+char *got_sha256_digest_to_str(const uint8_t *, char *, size_t);
+
+int got_parse_hash_digest(uint8_t *, const char *, enum got_hash_algorithm);
+int got_parse_object_id(struct got_object_id *, const char *,
+    enum got_hash_algorithm);
blob - fb4d3a30adf9281507aea3424f4c2711b1d3a28c
blob + 51a9a0ca1ab1e8d6bc5e9f6722d0595f2a3b5fe7
--- lib/hash.c
+++ lib/hash.c
@@ -15,13 +15,18 @@
  */
 
 #include <sys/types.h>
+#include <sys/queue.h>
+
 #include <sha1.h>
 #include <sha2.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <limits.h>
 
+#include "got_object.h"
+
 #include "got_lib_hash.h"
 
 int
@@ -41,14 +46,14 @@ got_parse_xdigit(uint8_t *val, const char *hex)
 	return 1;
 }
 
-int
-got_parse_sha1_digest(uint8_t *digest, const char *line)
+static int
+parse_digest(uint8_t *digest, int len, const char *line)
 {
 	uint8_t b = 0;
 	char hex[3] = {'\0', '\0', '\0'};
 	int i, j;
 
-	for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
+	for (i = 0; i < len; i++) {
 		if (line[0] == '\0' || line[1] == '\0')
 			return 0;
 		for (j = 0; j < 2; j++) {
@@ -63,17 +68,14 @@ got_parse_sha1_digest(uint8_t *digest, const char *lin
 	return 1;
 }
 
-char *
-got_sha1_digest_to_str(const uint8_t *digest, char *buf, size_t size)
+static char *
+digest_to_str(const uint8_t *digest, int len, char *buf)
 {
 	char *p = buf;
 	char hex[3];
 	int i;
 
-	if (size < SHA1_DIGEST_STRING_LENGTH)
-		return NULL;
-
-	for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
+	for (i = 0; i < len; i++) {
 		snprintf(hex, sizeof(hex), "%.2x", digest[i]);
 		p[0] = hex[0];
 		p[1] = hex[1];
@@ -83,3 +85,46 @@ got_sha1_digest_to_str(const uint8_t *digest, char *bu
 
 	return buf;
 }
+
+char *
+got_sha1_digest_to_str(const uint8_t *digest, char *buf, size_t size)
+{
+	if (size < SHA1_DIGEST_STRING_LENGTH)
+		return NULL;
+	return digest_to_str(digest, SHA1_DIGEST_LENGTH, buf);
+}
+
+char *
+got_sha256_digest_to_str(const uint8_t *digest, char *buf, size_t size)
+{
+	if (size < SHA256_DIGEST_STRING_LENGTH)
+		return NULL;
+	return digest_to_str(digest, SHA256_DIGEST_LENGTH, buf);
+}
+
+int
+got_parse_hash_digest(uint8_t *digest, const char *line,
+    enum got_hash_algorithm algo)
+{
+	switch (algo) {
+	case GOT_HASH_SHA1:
+		return parse_digest(digest, SHA1_DIGEST_LENGTH, line);
+	case GOT_HASH_SHA256:
+		return parse_digest(digest, SHA256_DIGEST_LENGTH, line);
+	default:
+		return 0;
+	}
+}
+
+int
+got_parse_object_id(struct got_object_id *id, const char *line,
+    enum got_hash_algorithm algo)
+{
+	memset(id, 0, sizeof(*id));
+
+	/* XXX: temporary until we grow got_object_id */
+	if (algo != GOT_HASH_SHA1)
+		return 0;
+
+	return got_parse_hash_digest(id->sha1, line, algo);
+}
blob - 4ef56fa20be5663cfbadd88d65956dfc21e3bc16
blob + 97affdf903ed7167bbc13755ab5b9700b855d3df
--- lib/object.c
+++ lib/object.c
@@ -152,7 +152,7 @@ got_object_open_by_id_str(struct got_object **obj, str
 {
 	struct got_object_id id;
 
-	if (!got_parse_sha1_digest(id.sha1, id_str))
+	if (!got_parse_object_id(&id, id_str, GOT_HASH_SHA1))
 		return got_error_path(id_str, GOT_ERR_BAD_OBJ_ID_STR);
 
 	return got_object_open(obj, repo, &id);
blob - d9f9ca9342e72dc31a186ed29f25340cc436e026
blob + cf8aa40383845a1abf060903091e267434ab01fe
--- lib/object_parse.c
+++ lib/object_parse.c
@@ -387,7 +387,7 @@ got_object_commit_add_parent(struct got_commit_object 
 	if (err)
 		return err;
 
-	if (!got_parse_sha1_digest(qid->id.sha1, id_str)) {
+	if (!got_parse_object_id(&qid->id, id_str, GOT_HASH_SHA1)) {
 		err = got_error(GOT_ERR_BAD_OBJ_DATA);
 		got_object_qid_free(qid);
 		return err;
@@ -620,6 +620,7 @@ got_object_parse_commit(struct got_commit_object **com
     size_t len)
 {
 	const struct got_error *err = NULL;
+	enum got_hash_algorithm algo = GOT_HASH_SHA1;
 	char *s = buf;
 	size_t label_len;
 	ssize_t remain = (ssize_t)len;
@@ -639,7 +640,7 @@ got_object_parse_commit(struct got_commit_object **com
 			goto done;
 		}
 		s += label_len;
-		if (!got_parse_sha1_digest((*commit)->tree_id->sha1, s)) {
+		if (!got_parse_object_id((*commit)->tree_id, s, algo)) {
 			err = got_error(GOT_ERR_BAD_OBJ_DATA);
 			goto done;
 		}
@@ -974,6 +975,7 @@ const struct got_error *
 got_object_parse_tag(struct got_tag_object **tag, uint8_t *buf, size_t len)
 {
 	const struct got_error *err = NULL;
+	enum got_hash_algorithm algo = GOT_HASH_SHA1;
 	size_t remain = len;
 	char *s = buf;
 	size_t label_len;
@@ -993,7 +995,7 @@ got_object_parse_tag(struct got_tag_object **tag, uint
 			goto done;
 		}
 		s += label_len;
-		if (!got_parse_sha1_digest((*tag)->id.sha1, s)) {
+		if (!got_parse_object_id(&(*tag)->id, s, algo)) {
 			err = got_error(GOT_ERR_BAD_OBJ_DATA);
 			goto done;
 		}
blob - 907dd4c008e199ac9a5aaea0988c4b560c5e48da
blob + ae7d854ac02878d29587b36f032f1e19a768519a
--- lib/patch.c
+++ lib/patch.c
@@ -705,7 +705,7 @@ open_blob(char **path, FILE **fp, const char *blobid,
 			return err;
 		idptr = matched_id;
 	} else {
-		if (!got_parse_sha1_digest(id.sha1, blobid))
+		if (!got_parse_object_id(&id, blobid, GOT_HASH_SHA1))
 			return got_error(GOT_ERR_BAD_OBJ_ID_STR);
 		idptr = &id;
 	}
blob - 8395bfeace67cdc2bb1963683124b6e736e2b829
blob + c5b60153156227720788e04eee9500140bafb6ee
--- lib/reference.c
+++ lib/reference.c
@@ -156,6 +156,7 @@ static const struct got_error *
 parse_ref_line(struct got_reference **ref, const char *name, const char *line,
     time_t mtime)
 {
+	enum got_hash_algorithm algo = GOT_HASH_SHA1;
 	struct got_object_id id;
 
 	if (strncmp(line, "ref: ", 5) == 0) {
@@ -163,7 +164,7 @@ parse_ref_line(struct got_reference **ref, const char 
 		return parse_symref(ref, name, line);
 	}
 
-	if (!got_parse_sha1_digest(id.sha1, line))
+	if (!got_parse_object_id(&id, line, algo))
 		return got_error(GOT_ERR_BAD_REF_DATA);
 
 	return alloc_ref(ref, name, &id, 0, mtime);
@@ -293,6 +294,7 @@ static const struct got_error *
 parse_packed_ref_line(struct got_reference **ref, const char *abs_refname,
     const char *line, time_t mtime)
 {
+	enum got_hash_algorithm algo = GOT_HASH_SHA1;
 	struct got_object_id id;
 	const char *name;
 
@@ -301,7 +303,7 @@ parse_packed_ref_line(struct got_reference **ref, cons
 	if (line[0] == '#' || line[0] == '^')
 		return NULL;
 
-	if (!got_parse_sha1_digest(id.sha1, line))
+	if (!got_parse_object_id(&id, line, algo))
 		return got_error(GOT_ERR_BAD_REF_DATA);
 
 	if (abs_refname) {
blob - 3a7d41743859cdc6a9849f722ab1316fd01c3378
blob + 2e2af368123ed1e79a0a36460803376dcef2ee53
--- lib/repository.c
+++ lib/repository.c
@@ -1735,6 +1735,7 @@ match_loose_object(struct got_object_id **unique_id, c
 	}
 	while ((dent = readdir(dir)) != NULL) {
 		int cmp;
+		enum got_hash_algorithm algo = GOT_HASH_SHA1;
 
 		free(id_str);
 		id_str = NULL;
@@ -1748,7 +1749,7 @@ match_loose_object(struct got_object_id **unique_id, c
 			goto done;
 		}
 
-		if (!got_parse_sha1_digest(id.sha1, id_str))
+		if (!got_parse_object_id(&id, id_str, algo))
 			continue;
 
 		/*
@@ -2288,6 +2289,7 @@ got_repo_get_loose_object_info(int *nobjects, off_t *o
 			char *id_str;
 			int fd;
 			struct stat sb;
+			enum got_hash_algorithm algo = GOT_HASH_SHA1;
 
 			if (strcmp(dent->d_name, ".") == 0 ||
 			    strcmp(dent->d_name, "..") == 0)
@@ -2298,7 +2300,7 @@ got_repo_get_loose_object_info(int *nobjects, off_t *o
 				goto done;
 			}
 
-			if (!got_parse_sha1_digest(id.sha1, id_str)) {
+			if (!got_parse_object_id(&id, id_str, algo)) {
 				free(id_str);
 				continue;
 			}
blob - 199a3f8e3e341c8bff1f5832c6940113a46aec4e
blob + 773e2a105d455b57754818c3edca08544cac6dae
--- lib/repository_admin.c
+++ lib/repository_admin.c
@@ -483,7 +483,7 @@ got_repo_find_pack(FILE **packfile, struct got_object_
 		goto done;
 	}
 	*dot = '\0';
-	if (!got_parse_sha1_digest(id.sha1, p)) {
+	if (!got_parse_object_id(&id, p, GOT_HASH_SHA1)) {
 		err = got_error_fmt(GOT_ERR_BAD_PATH,
 		    "'%s' is not a valid pack file name",
 		    packfile_name);
@@ -682,8 +682,8 @@ get_loose_object_ids(struct got_object_idset **loose_i
 				goto done;
 			}
 
-			memset(&id, 0, sizeof(id));
-			if (!got_parse_sha1_digest(id.sha1, id_str)) {
+			if (!got_parse_object_id(&id, id_str,
+			    GOT_HASH_SHA1)) {
 				free(id_str);
 				continue;
 			}
blob - 9ce8b57d42611e46e1bd5ae68821685cc61c22f4
blob + ce632a4ddd71b532b651477639e7725712086a30
--- lib/serve.c
+++ lib/serve.c
@@ -36,6 +36,7 @@
 #include "got_path.h"
 #include "got_version.h"
 #include "got_reference.h"
+#include "got_object.h"
 
 #include "got_lib_pkt.h"
 #include "got_lib_dial.h"
@@ -433,7 +434,7 @@ parse_want_line(char **common_capabilities, uint8_t *i
 	if (err)
 		return err;
 
-	if (!got_parse_sha1_digest(id, id_str)) {
+	if (!got_parse_hash_digest(id, id_str, GOT_HASH_SHA1)) {
 		err = got_error_msg(GOT_ERR_BAD_PACKET,
 		    "want-line with bad object ID");
 		goto done;
@@ -462,7 +463,7 @@ parse_have_line(uint8_t *id, char *buf, size_t len)
 	if (err)
 		return err;
 
-	if (!got_parse_sha1_digest(id, id_str)) {
+	if (!got_parse_hash_digest(id, id_str, GOT_HASH_SHA1)) {
 		err = got_error_msg(GOT_ERR_BAD_PACKET,
 		    "have-line with bad object ID");
 		goto done;
@@ -1049,8 +1050,8 @@ parse_ref_update_line(char **common_capabilities, char
 	if (err)
 		return err;
 
-	if (!got_parse_sha1_digest(old_id, old_id_str) ||
-	    !got_parse_sha1_digest(new_id, new_id_str)) {
+	if (!got_parse_hash_digest(old_id, old_id_str, GOT_HASH_SHA1) ||
+	    !got_parse_hash_digest(new_id, new_id_str, GOT_HASH_SHA1)) {
 		err = got_error_msg(GOT_ERR_BAD_PACKET,
 		    "ref-update with bad object ID");
 		goto done;
blob - 08cd48242d80bee13639c2b118d56b1ae63b12ea
blob + ec59143034ebc8d6aae743d264ae980a963b239b
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
@@ -301,7 +301,7 @@ fetch_ref(struct imsgbuf *ibuf, struct got_pathlist_he
 	const struct got_error *err;
 	char *theirs = NULL, *mine = NULL;
 
-	if (!got_parse_sha1_digest(want->sha1, id_str)) {
+	if (!got_parse_object_id(want, id_str, GOT_HASH_SHA1)) {
 		err = got_error(GOT_ERR_BAD_OBJ_ID_STR);
 		goto done;
 	}
@@ -620,7 +620,8 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
 			    "unexpected message from server");
 			goto done;
 		}
-		if (!got_parse_sha1_digest(common_id.sha1, buf + 4)) {
+		if (!got_parse_object_id(&common_id, buf + 4,
+		    GOT_HASH_SHA1)) {
 			err = got_error_msg(GOT_ERR_BAD_PACKET,
 			    "bad object ID in ACK packet from server");
 			goto done;
blob - a2e4e1de5f50b7d195f309b051b448e82c5db505
blob + aba67e27deae3821dd78da675ebab6b45d0cc74b
--- libexec/got-read-patch/got-read-patch.c
+++ libexec/got-read-patch/got-read-patch.c
@@ -194,7 +194,7 @@ blobid(const char *line, char **blob, int git)
 	if ((*blob = strndup(line, len)) == NULL)
 		return got_error_from_errno("strndup");
 
-	if (!git && !got_parse_sha1_digest(digest, *blob)) {
+	if (!git && !got_parse_hash_digest(digest, *blob, GOT_HASH_SHA1)) {
 		/* silently ignore invalid blob ids */
 		free(*blob);
 		*blob = NULL;
blob - 902a0a8ab722ccfd8def0d5a6a32823394675f96
blob + 752961b1658d0cf2c9d25fda7a0a592ae495cce0
--- libexec/got-send-pack/got-send-pack.c
+++ libexec/got-send-pack/got-send-pack.c
@@ -413,7 +413,7 @@ send_pack(int fd, struct got_pathlist_head *refs,
 			err = got_error_from_errno("malloc");
 			goto done;
 		}
-		if (!got_parse_sha1_digest(id->sha1, id_str)) {
+		if (!got_parse_object_id(id, id_str, GOT_HASH_SHA1)) {
 			err = got_error(GOT_ERR_BAD_OBJ_ID_STR);
 			goto done;
 		}
blob - 511fd016b578a9308aede2f46618c2b7b6a353c2
blob + 590110e141628fad3b6bacc7d6054bc81b3ceec8
--- regress/idset/idset_test.c
+++ regress/idset/idset_test.c
@@ -70,15 +70,15 @@ idset_add_remove_iter(void)
 		goto done;
 	}
 
-	if (!got_parse_sha1_digest(id1.sha1, id_str1)) {
+	if (!got_parse_object_id(&id1, id_str1, GOT_HASH_SHA1)) {
 		err = got_error(GOT_ERR_BAD_OBJ_ID_STR);
 		goto done;
 	}
-	if (!got_parse_sha1_digest(id2.sha1, id_str2)) {
+	if (!got_parse_object_id(&id2, id_str2, GOT_HASH_SHA1)) {
 		err = got_error(GOT_ERR_BAD_OBJ_ID_STR);
 		goto done;
 	}
-	if (!got_parse_sha1_digest(id3.sha1, id_str3)) {
+	if (!got_parse_object_id(&id3, id_str3, GOT_HASH_SHA1)) {
 		err = got_error(GOT_ERR_BAD_OBJ_ID_STR);
 		goto done;
 	}