Commit 0cf1f444edd447aeaf61edefcaf5b31c2d611f7a

Patrick Steinhardt 2020-06-15T13:19:44

diff_print: handle errors when printing to file When printing the diff to a `FILE *` handle, we neither check the return value of fputc(3P) nor the one of fwrite(3P). As a result, we'll silently return successful even if we didn't print anything at all. Futhermore, the arguments to fwrite(3P) are reversed: we have one item of length `content_len`, and not `content_len` items of one byte. Fix both issues by checking return values as well as reversing the arguments to fwrite(3P).

diff --git a/src/diff_print.c b/src/diff_print.c
index 9ff6d9a..8f378d9 100644
--- a/src/diff_print.c
+++ b/src/diff_print.c
@@ -742,14 +742,27 @@ int git_diff_print_callback__to_file_handle(
 	void *payload)
 {
 	FILE *fp = payload ? payload : stdout;
+	int error;
 
-	GIT_UNUSED(delta); GIT_UNUSED(hunk);
+	GIT_UNUSED(delta);
+	GIT_UNUSED(hunk);
 
 	if (line->origin == GIT_DIFF_LINE_CONTEXT ||
-		line->origin == GIT_DIFF_LINE_ADDITION ||
-		line->origin == GIT_DIFF_LINE_DELETION)
-		fputc(line->origin, fp);
-	fwrite(line->content, 1, line->content_len, fp);
+	    line->origin == GIT_DIFF_LINE_ADDITION ||
+	    line->origin == GIT_DIFF_LINE_DELETION) {
+		while ((error = fputc(line->origin, fp)) == EINTR)
+			continue;
+		if (error) {
+			git_error_set(GIT_ERROR_OS, "could not write status");
+			return -1;
+		}
+	}
+
+	if (fwrite(line->content, line->content_len, 1, fp) != 1) {
+		git_error_set(GIT_ERROR_OS, "could not write line");
+		return -1;
+	}
+
 	return 0;
 }