summaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2011-05-20 17:20:12 (GMT)
committerJunio C Hamano <gitster@pobox.com>2011-05-20 18:39:49 (GMT)
commit42536dd9b9829b4eb4e3706e141b3c8bffa3e826 (patch)
treedb640fa331f2b513c593eda286400c2086c9ec5a /diff.c
parent5269edf1702b7375a287d5bbbb3c1b1f3a8aa765 (diff)
downloadgit-42536dd9b9829b4eb4e3706e141b3c8bffa3e826.zip
git-42536dd9b9829b4eb4e3706e141b3c8bffa3e826.tar.gz
git-42536dd9b9829b4eb4e3706e141b3c8bffa3e826.tar.bz2
do not read beyond end of malloc'd buffer
With diff.suppress-blank-empty=true, "git diff --word-diff" would output data that had been read from uninitialized heap memory. The problem was that fn_out_consume did not account for the possibility of a line with length 1, i.e., the empty context line that diff.suppress-blank-empty=true converts from " \n" to "\n". Since it assumed there would always be a prefix character (the space), it decremented "len" unconditionally, thus passing len=0 to emit_line, which would then blindly call emit_line_0 with len=-1 which would pass that value on to fwrite as SIZE_MAX. Boom. Signed-off-by: Jim Meyering <meyering@redhat.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/diff.c b/diff.c
index 5422c43..f90c7a8 100644
--- a/diff.c
+++ b/diff.c
@@ -1043,8 +1043,16 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
emit_line(ecbdata->opt, plain, reset, line, len);
fputs("~\n", ecbdata->opt->file);
} else {
- /* don't print the prefix character */
- emit_line(ecbdata->opt, plain, reset, line+1, len-1);
+ /*
+ * Skip the prefix character, if any. With
+ * diff_suppress_blank_empty, there may be
+ * none.
+ */
+ if (line[0] != '\n') {
+ line++;
+ len--;
+ }
+ emit_line(ecbdata->opt, plain, reset, line, len);
}
return;
}