Commit 552e23ba566d975b4dd48163b91021892504f021

Ramsay Jones 2010-06-02T19:16:28

Fix a bug in the git_oid_to_string() function When git_oid_to_string() was passed a buffer size larger than GIT_OID_HEXSZ+1, the function placed the c-string NUL char at the wrong position. Fix the code to place the NUL at the end of the (possibly truncated) oid string. Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>

diff --git a/src/oid.c b/src/oid.c
index 182859f..0bc152b 100644
--- a/src/oid.c
+++ b/src/oid.c
@@ -106,7 +106,9 @@ char *git_oid_to_string(char *out, size_t n, const git_oid *oid)
 
 	if (n > 0) {
 		git_oid_fmt(str, oid);
-		memcpy(out, str, n > GIT_OID_HEXSZ ? GIT_OID_HEXSZ : n);
+		if (n > GIT_OID_HEXSZ)
+			n = GIT_OID_HEXSZ;
+		memcpy(out, str, n);
 	}
 
 	out[n] = '\0';
diff --git a/tests/t0101-oid.c b/tests/t0101-oid.c
index c867e4f..3f61a75 100644
--- a/tests/t0101-oid.c
+++ b/tests/t0101-oid.c
@@ -251,3 +251,28 @@ BEGIN_TEST(oid_to_string)
 	must_pass(strcmp(exp, out));
 END_TEST
 
+BEGIN_TEST(oid_to_string_big)
+	const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
+	git_oid in;
+	char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */
+	char *str;
+
+	must_pass(git_oid_mkstr(&in, exp));
+
+	/* place some tail material */
+	big[GIT_OID_HEXSZ+0] = 'W'; /* should be '\0' afterwards */
+	big[GIT_OID_HEXSZ+1] = 'X'; /* should remain untouched   */
+	big[GIT_OID_HEXSZ+2] = 'Y'; /* ditto */
+	big[GIT_OID_HEXSZ+3] = 'Z'; /* ditto */
+
+	/* returns big as hex formatted c-string */
+	str = git_oid_to_string(big, sizeof(big), &in);
+	must_be_true(str && str == big && *(str+GIT_OID_HEXSZ) == '\0');
+	must_pass(strcmp(exp, big));
+
+	/* check tail material is untouched */
+	must_be_true(str && str == big && *(str+GIT_OID_HEXSZ+1) == 'X');
+	must_be_true(str && str == big && *(str+GIT_OID_HEXSZ+2) == 'Y');
+	must_be_true(str && str == big && *(str+GIT_OID_HEXSZ+3) == 'Z');
+END_TEST
+