Regression test for CVE-2026-53910, fixed in commits 73ed7ce85cc7
("diff3: check for integer overflows when reading line numbers from
diff") and 9ff04d5b8474 ("diff3: prevent overflow in line offsets").

readnum accepted line numbers larger than LIN_MAX, silently wrapping
them to a bogus value instead of rejecting the input.  Drive diff3 with
a stub --diff-program that emits a control line with an out-of-range
line number and check that diff3 fails cleanly rather than acting on the
wrapped value.

* tests/CVE-2026-53910-test: New test.
* tests/Makefile.am (TESTS): Add it.

AI-Generated: Uses Kiro CLI
Signed-off-by: Pratik Farkase <[email protected]>
---
 tests/CVE-2026-53910-test | 46 +++++++++++++++++++++++++++++++++++++++
 tests/Makefile.am         |  1 +
 2 files changed, 47 insertions(+)
 create mode 100755 tests/CVE-2026-53910-test

diff --git a/tests/CVE-2026-53910-test b/tests/CVE-2026-53910-test
new file mode 100755
index 0000000..d137425
--- /dev/null
+++ b/tests/CVE-2026-53910-test
@@ -0,0 +1,46 @@
+#!/bin/sh
+# Regression test for an integer overflow in diff3's readnum (CVE-2026-53910).
+#
+# This test was generated with the assistance of an AI tool.
+#
+# diff3 parses line numbers out of the diff program's output.  Before the
+# fix, readnum accumulated digits with "num = c - '0' + num * 10" and never
+# checked for overflow, so a line number larger than LIN_MAX silently wrapped
+# to a bogus in-range value and diff3 proceeded to use it.  After the fix,
+# readnum rejects an out-of-range line number and diff3 fails cleanly with a
+# "diff failed" diagnostic instead of emitting garbage.
+#
+# We drive diff3 with a stub --diff-program that prints a normal-diff control
+# line whose first line number (20 nines) exceeds LIN_MAX on any current
+# platform, so the behaviour does not depend on the real diff or on the input
+# files having an impractically large number of lines.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+# A stand-in "diff" that emits a control line with an overflowing line number.
+cat <<'EOF' > fake-diff || framework_failure_
+#!/bin/sh
+echo '99999999999999999999c1'
+echo '< a'
+echo '---'
+echo '> b'
+EOF
+chmod +x fake-diff || framework_failure_
+
+echo a > a || framework_failure_
+echo b > b || framework_failure_
+echo c > c || framework_failure_
+
+fail=0
+
+# With the overflow fix in place diff3 must reject the bogus line number.
+# Prior to the fix diff3 silently wrapped it (e.g. to 7766279631452241919)
+# and exited 0, so "returns_ 2" fails on a vulnerable diff3.
+returns_ 2 diff3 --diff-program="./fake-diff" a b c > out 2> err || fail=1
+
+# The diagnostic must name the offending control line, and the wrapped
+# value must never appear in either stream.
+grep 'diff failed' err || fail=1
+grep '77662796' out err && fail=1
+
+Exit $fail
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 47449fc..bd88fe4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -9,6 +9,7 @@ TESTS = \
   cmp \
   colliding-file-names \
   diff3 \
+  CVE-2026-53910-test \
   empty-file \
   excess-slash \
   expand-tabs \
-- 
2.43.0




Reply via email to