summaryrefslogtreecommitdiff
path: root/rerere.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2015-07-24 16:01:48 -0700
committerJunio C Hamano <gitster@pobox.com>2015-07-24 16:02:02 -0700
commitd3c2749def9563798cea3486f3793ad36d9c1030 (patch)
tree900977965020d117b6f45364062f2da3e45c9f1c /rerere.c
parenta96847cc1691840bd95cc56549d7c00b35f6d5a0 (diff)
downloadgit-d3c2749def9563798cea3486f3793ad36d9c1030.tar.gz
rerere: fix benign off-by-one non-bug and clarify code
rerere_io_putconflict() wants to use a limited fixed-sized buf[] on stack repeatedly to formulate a longer string, but its implementation is doubly confusing: * When it knows that the whole thing fits in buf[], it wants to fill early part of buf[] with conflict marker characters, followed by a LF and a NUL. It miscounts the size of the buffer by 1 and does not use the last byte of buf[]. * When it needs to show only the early part of a long conflict marker string (because the whole thing does not fit in buf[]), it adjusts the number of bytes shown in the current round in a strange-looking way. It makes sure that this round does not emit all bytes and leaves at least one byte to the next round, so that "it all fits" case will pick up the rest and show the terminating LF. While this is correct, one needs to stop and think for a while to realize why it is correct without an explanation. Fix the benign off-by-one, and add comments to explain the strange-looking size adjustment. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'rerere.c')
-rw-r--r--rerere.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/rerere.c b/rerere.c
index 7db5b54838..6fd8c5d3af 100644
--- a/rerere.c
+++ b/rerere.c
@@ -125,13 +125,20 @@ static void rerere_io_putconflict(int ch, int size, struct rerere_io *io)
char buf[64];
while (size) {
- if (size < sizeof(buf) - 2) {
+ if (size <= sizeof(buf) - 2) {
memset(buf, ch, size);
buf[size] = '\n';
buf[size + 1] = '\0';
size = 0;
} else {
int sz = sizeof(buf) - 1;
+
+ /*
+ * Make sure we will not write everything out
+ * in this round by leaving at least 1 byte
+ * for the next round, giving the next round
+ * a chance to add the terminating LF. Yuck.
+ */
if (size <= sz)
sz -= (sz - size) + 1;
memset(buf, ch, sz);