diff options
author | Patrick Steinhardt <ps@pks.im> | 2020-06-15 13:19:44 +0200 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2020-06-17 07:34:10 +0200 |
commit | 0cf1f444edd447aeaf61edefcaf5b31c2d611f7a (patch) | |
tree | 08e243ddb3c52cd654fde38452893ac7930f175b | |
parent | d60bf0022e4d51c13f9395b7668e9f6ce389bf25 (diff) | |
download | libgit2-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.c | 23 |
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; } |