From: "René Scharfe" <l.s.r@web.de>
To: Jason Cho <jason11choca@proton.me>,
"git@vger.kernel.org" <git@vger.kernel.org>
Subject: [PATCH] xdiff: avoid arithmetic overflow in xdl_get_hunk()
Date: Fri, 14 Mar 2025 23:00:42 +0100 [thread overview]
Message-ID: <4e9b6b4c-aaa1-4c6f-93f4-7bb04607e843@web.de> (raw)
In-Reply-To: <NYMqsJ7uttDzFT2OOEg5LLsxCSoQhTzqBs16KrMHGEKC7LzOAiYnYTEZavRQWqGH41UgjdwScwer7MssNzI7AEDHnD8GTBWvoBIqJ2e7D6g=@proton.me>
xdl_get_hunk() calculates the maximum number of common lines between two
changes that would fit into the same hunk for the given context options.
It involves doubling and addition and thus can overflow if the terms are
huge.
The type of ctxlen and interhunkctxlen in xdemitconf_t is long, while
the type of the corresponding context and interhunkcontext in struct
diff_options is int. On many platforms longs are bigger that ints,
which prevents the overflow. On Windows they have the same range and
the overflow manifests as hunks that are split erroneously and lines
being repeated between them.
Fix the overflow by checking and not going beyond LONG_MAX. This allows
specifying a huge context line count and getting all lines of a changed
files in a single hunk, as expected.
Reported-by: Jason Cho <jason11choca@proton.me>
Signed-off-by: René Scharfe <l.s.r@web.de>
---
t/t4055-diff-context.sh | 10 ++++++++++
xdiff/xemit.c | 8 +++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh
index f7ff234cf9..ec2804eea6 100755
--- a/t/t4055-diff-context.sh
+++ b/t/t4055-diff-context.sh
@@ -89,4 +89,14 @@ test_expect_success '-U0 is valid, so is diff.context=0' '
grep "^+MODIFIED" output
'
+test_expect_success '-U2147483647 works' '
+ echo APPENDED >>x &&
+ test_line_count = 16 x &&
+ git diff -U2147483647 >output &&
+ test_line_count = 22 output &&
+ grep "^-ADDED" output &&
+ grep "^+MODIFIED" output &&
+ grep "^+APPENDED" output
+'
+
test_done
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index f8e3f25b03..1d40c9cb40 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -43,6 +43,10 @@ static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *
return 0;
}
+static long saturating_add(long a, long b)
+{
+ return signed_add_overflows(a, b) ? LONG_MAX : a + b;
+}
/*
* Starting at the passed change atom, find the latest change atom to be included
@@ -52,7 +56,9 @@ static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *
xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
{
xdchange_t *xch, *xchp, *lxch;
- long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;
+ long max_common = saturating_add(saturating_add(xecfg->ctxlen,
+ xecfg->ctxlen),
+ xecfg->interhunkctxlen);
long max_ignorable = xecfg->ctxlen;
long ignored = 0; /* number of ignored blank lines */
--
2.48.1
next prev parent reply other threads:[~2025-03-14 22:00 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <xXWgbH3mlNEvFcdGLqBHwcclZoeZNPoLg8Hr6YCipHXvS5eKaHeTppzFM-l_wyB46BB1R1T0j6g_jWRXIj7-GRJh1LPxi1ta3GkQ5t8F4-0=@proton.me>
2025-03-12 15:51 ` Iffy output given git diff --unified=2147483647 Jason Cho
2025-03-14 22:00 ` René Scharfe [this message]
2025-03-14 22:28 ` [PATCH] xdiff: avoid arithmetic overflow in xdl_get_hunk() Junio C Hamano
2025-03-15 6:38 ` René Scharfe
2025-03-16 19:53 ` Junio C Hamano
2025-03-17 16:50 ` René Scharfe
2025-03-14 23:14 ` Jason Cho
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4e9b6b4c-aaa1-4c6f-93f4-7bb04607e843@web.de \
--to=l.s.r@web.de \
--cc=git@vger.kernel.org \
--cc=jason11choca@proton.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox