Commit 3d1c9f612d78c6c235a3f38af226300fb6dd7dd6

Russell Belfer 2013-05-09T06:45:06

Fix git_repository_message docs This clarifies the docs for git_repository_message and also adds to the tests to explicitly check NUL termination of data when the output buffer is smaller than the message size. There is a minor behavior change so that a non-NULL output buffer will always be NUL terminated (at length zero) if an error occurs.

diff --git a/include/git2/repository.h b/include/git2/repository.h
index cd238e1..e0464c6 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -460,10 +460,19 @@ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
  * Use this function to get the contents of this file. Don't forget to
  * remove the file after you create the commit.
  *
+ * If the repository message exists and there are no errors reading it, this
+ * returns the bytes needed to store the message in memory (i.e. message
+ * file size plus one terminating NUL byte).  That value is returned even if
+ * `out` is NULL or `len` is shorter than the necessary size.
+ *
+ * The `out` buffer will *always* be NUL terminated, even if truncation
+ * occurs.
+ *
  * @param out Buffer to write data into or NULL to just read required size
- * @param len Length of buffer in bytes
+ * @param len Length of `out` buffer in bytes
  * @param repo Repository to read prepared message from
- * @return Bytes written to buffer, GIT_ENOTFOUND if no message, or -1 on error
+ * @return GIT_ENOUTFOUND if no message exists, other value < 0 for other
+ *         errors, or total bytes in message (may be > `len`) on success
  */
 GIT_EXTERN(int) git_repository_message(char *out, size_t len, git_repository *repo);
 
diff --git a/src/repository.c b/src/repository.c
index e2cedc0..0b8fc39 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1596,6 +1596,9 @@ int git_repository_message(char *buffer, size_t len, git_repository *repo)
 	struct stat st;
 	int error;
 
+	if (buffer != NULL)
+		*buffer = '\0';
+
 	if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_MSG_FILE) < 0)
 		return -1;
 
diff --git a/tests-clar/repo/message.c b/tests-clar/repo/message.c
index 59487d5..629d40c 100644
--- a/tests-clar/repo/message.c
+++ b/tests-clar/repo/message.c
@@ -35,13 +35,18 @@ void test_repo_message__message(void)
 
 	len = git_repository_message(NULL, 0, _repo);
 	cl_assert(len > 0);
+
 	_actual = git__malloc(len + 1);
 	cl_assert(_actual != NULL);
 
+	/* Test non truncation */
 	cl_assert(git_repository_message(_actual, len, _repo) > 0);
-	_actual[len] = '\0';
 	cl_assert_equal_s(expected, _actual);
 
+	/* Test truncation and that trailing NUL is inserted */
+	cl_assert(git_repository_message(_actual, 6, _repo) > 0);
+	cl_assert_equal_s("Test\n", _actual);
+
 	cl_git_pass(p_unlink(git_buf_cstr(&_path)));
 	cl_assert_equal_i(GIT_ENOTFOUND, git_repository_message(NULL, 0, _repo));
 }