Commit e0f3c33d5a505f5341300351c2fcc493929a932f

Edward Thomson 2020-04-05T11:22:19

buffer: git_buf_copy_cstr should return a value `git_buf_copy_cstr` is called with user-input, and wants to sanity-check that input. Allow it to return a value if the input was malformed in a way that we cannot cope.

diff --git a/src/buffer.c b/src/buffer.c
index 2928b17..f6ecc6e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -556,22 +556,26 @@ int git_buf_printf(git_buf *buf, const char *format, ...)
 	return r;
 }
 
-void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf)
+int git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf)
 {
 	size_t copylen;
 
-	assert(data && datasize && buf);
+	GIT_ASSERT_ARG(data);
+	GIT_ASSERT_ARG(datasize);
+	GIT_ASSERT_ARG(buf);
 
 	data[0] = '\0';
 
 	if (buf->size == 0 || buf->asize <= 0)
-		return;
+		return 0;
 
 	copylen = buf->size;
 	if (copylen > datasize - 1)
 		copylen = datasize - 1;
 	memmove(data, buf->ptr, copylen);
 	data[copylen] = '\0';
+
+	return 0;
 }
 
 void git_buf_consume_bytes(git_buf *buf, size_t len)
diff --git a/src/buffer.h b/src/buffer.h
index 6257b43..8c2096b 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -145,7 +145,7 @@ GIT_INLINE(size_t) git_buf_len(const git_buf *buf)
 	return buf->size;
 }
 
-void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf);
+int git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf);
 
 #define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1)
 
diff --git a/src/refs.c b/src/refs.c
index 497b066..71594d7 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -1024,7 +1024,8 @@ int git_reference_normalize_name(
 		goto cleanup;
 	}
 
-	git_buf_copy_cstr(buffer_out, buffer_size, &buf);
+	if ((error = git_buf_copy_cstr(buffer_out, buffer_size, &buf)) < 0)
+		goto cleanup;
 
 	error = 0;