summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2020-06-15 13:19:44 +0200
committerPatrick Steinhardt <ps@pks.im>2020-06-17 07:34:10 +0200
commit0cf1f444edd447aeaf61edefcaf5b31c2d611f7a (patch)
tree08e243ddb3c52cd654fde38452893ac7930f175b
parentd60bf0022e4d51c13f9395b7668e9f6ce389bf25 (diff)
downloadlibgit2-0cf1f444edd447aeaf61edefcaf5b31c2d611f7a.tar.gz
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).
-rw-r--r--src/diff_print.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/diff_print.c b/src/diff_print.c
index 9ff6d9a7a..8f378d9ef 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;
}