Commit ef0981d5bfbea78904cdedaaa342f68545e4be79

Stefan Sperling 2018-02-12T22:40:55

make length of id string an implementation detail

diff --git a/include/got_object.h b/include/got_object.h
index 197e0e0..b7f5af9 100644
--- a/include/got_object.h
+++ b/include/got_object.h
@@ -57,7 +57,7 @@ struct got_object;
 
 struct got_repository;
 
-char *got_object_id_str(struct got_object_id *, char *, size_t);
+const struct got_error *got_object_id_str(char **, struct got_object_id *);
 int got_object_id_cmp(struct got_object_id *, struct got_object_id *);
 int got_object_get_type(struct got_object *);
 const struct got_error *got_object_open(struct got_object **,
diff --git a/lib/object.c b/lib/object.c
index 0cabc1b..1ec85ca 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -52,10 +52,22 @@
 #define GOT_COMMIT_TAG_AUTHOR		"author "
 #define GOT_COMMIT_TAG_COMMITTER	"committer "
 
-char *
-got_object_id_str(struct got_object_id *id, char *buf, size_t size)
+const struct got_error *
+got_object_id_str(char **outbuf, struct got_object_id *id)
 {
-	return got_sha1_digest_to_str(id->sha1, buf, size);
+	static const size_t len = SHA1_DIGEST_STRING_LENGTH;
+
+	*outbuf = calloc(1, len);
+	if (*outbuf == NULL)
+		return got_error(GOT_ERR_NO_MEM);
+
+	if (got_sha1_digest_to_str(id->sha1, *outbuf, len) == NULL) {
+		free(*outbuf);
+		*outbuf = NULL;
+		return got_error(GOT_ERR_BAD_OBJ_ID_STR);
+	}
+
+	return NULL;
 }
 
 int
@@ -182,18 +194,21 @@ static const struct got_error *
 object_path(char **path, struct got_object_id *id, struct got_repository *repo)
 {
 	const struct got_error *err = NULL;
-	char hex[SHA1_DIGEST_STRING_LENGTH];
+	char *hex;
 	char *path_objects = got_repo_get_path_objects(repo);
 
 	if (path_objects == NULL)
 		return got_error(GOT_ERR_NO_MEM);
 
-	got_object_id_str(id, hex, sizeof(hex));
+	err = got_object_id_str(&hex, id);
+	if (err)
+		return err;
 
 	if (asprintf(path, "%s/%.2x/%s", path_objects,
 	    id->sha1[0], hex + 2) == -1)
 		err = got_error(GOT_ERR_NO_MEM);
 
+	free(hex);
 	free(path_objects);
 	return err;
 }
@@ -349,7 +364,7 @@ parse_commit_object(struct got_commit_object **commit, char *buf, size_t len)
 		if (remain < SHA1_DIGEST_STRING_LENGTH) {
 			err = got_error(GOT_ERR_BAD_OBJ_DATA);
 			goto done;
-		}	
+		}
 
 		pid = calloc(1, sizeof(*pid));
 		if (pid == NULL) {
diff --git a/regress/repository/repository_test.c b/regress/repository/repository_test.c
index 510c96d..3d4d249 100644
--- a/regress/repository/repository_test.c
+++ b/regress/repository/repository_test.c
@@ -80,7 +80,6 @@ print_tree_object(struct got_object *obj, char *parent,
 	struct got_tree_object *tree;
 	struct got_tree_entry *te;
 	const struct got_error *err;
-	char hex[SHA1_DIGEST_STRING_LENGTH];
 
 	err = got_object_tree_open(&tree, repo, obj);
 	if (err != NULL)
@@ -89,16 +88,18 @@ print_tree_object(struct got_object *obj, char *parent,
 	SIMPLEQ_FOREACH(te, &tree->entries, entry) {
 		struct got_object *treeobj;
 		char *next_parent;
+		char *hex;
+
+		err = got_object_id_str(&hex, te->id);
+		if (err)
+			break;
 
 		if (!S_ISDIR(te->mode)) {
-			test_printf("%s %s/%s\n",
-			    got_object_id_str(te->id, hex, sizeof(hex)),
-			    parent, te->name);
+			test_printf("%s %s/%s\n", hex, parent, te->name);
 			continue;
 		}
-		test_printf("%s %s/%s\n",
-		    got_object_id_str(te->id, hex, sizeof(hex)),
-		    parent, te->name);
+		test_printf("%s %s/%s\n", hex, parent, te->name);
+		free(hex);
 
 		err = got_object_open(&treeobj, repo, te->id);
 		if (err != NULL)
@@ -135,20 +136,26 @@ print_commit_object(struct got_object *obj, struct got_repository *repo)
 {
 	struct got_commit_object *commit;
 	struct got_parent_id *pid;
-	char buf[SHA1_DIGEST_STRING_LENGTH];
+	char *buf;
 	const struct got_error *err;
 	struct got_object* treeobj;
 
 	err = got_object_commit_open(&commit, repo, obj);
-	if (err != NULL)
+	if (err)
 		return err;
 
-	test_printf("tree: %s\n",
-	    got_object_id_str(commit->tree_id, buf, sizeof(buf)));
+	err = got_object_id_str(&buf, commit->tree_id);
+	if (err)
+		return err;
+	test_printf("tree: %s\n", buf);
+	free(buf);
 	test_printf("parent%s: ", (commit->nparents == 1) ? "" : "s");
 	SIMPLEQ_FOREACH(pid, &commit->parent_ids, entry) {
-		test_printf("%s\n",
-		    got_object_id_str(pid->id, buf, sizeof(buf)));
+		err = got_object_id_str(&buf, pid->id);
+		if (err)
+			return err;
+		test_printf("%s\n", buf);
+		free(buf);
 	}
 	test_printf("author: %s\n", commit->author);
 	test_printf("committer: %s\n", commit->committer);
@@ -177,7 +184,7 @@ repo_read_log(const char *repo_path)
 	struct got_reference *head_ref;
 	struct got_object_id *id;
 	struct got_object *obj;
-	char buf[SHA1_DIGEST_STRING_LENGTH];
+	char *buf;
 	int ret;
 
 	err = got_repo_open(&repo, repo_path);
@@ -189,7 +196,11 @@ repo_read_log(const char *repo_path)
 	err = got_ref_resolve(&id, repo, head_ref);
 	if (err != NULL || head_ref == NULL)
 		return 0;
-	test_printf("HEAD is at %s\n", got_object_id_str(id, buf, sizeof(buf)));
+	err = got_object_id_str(&buf, id);
+	if (err != NULL)
+		return 0;
+	test_printf("HEAD is at %s\n", buf);
+	free(buf);
 	err = got_object_open(&obj, repo, id);
 	if (err != NULL || obj == NULL)
 		return 0;