From 592dbcf6579f6903d8ff4f306bb699b3148e2a49 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Thu, 18 Jun 2026 11:38:42 -0700 Subject: [PATCH] flipdiff: avoid crash on non-commuting patches Signed-off-by: Sai Asish Y --- Makefile.am | 1 + src/interdiff.c | 9 +++++++++ tests/flip20/run-test | 30 ++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100755 tests/flip20/run-test diff --git a/Makefile.am b/Makefile.am index 55e0717..edc8c5b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -286,6 +286,7 @@ TESTS = tests/newline1/run-test \ tests/flip17/run-test \ tests/flip18/run-test \ tests/flip19/run-test \ + tests/flip20/run-test \ tests/unline1/run-test \ tests/nul0/run-test \ tests/nul1/run-test \ diff --git a/src/interdiff.c b/src/interdiff.c index 96f5a92..a3c1ecb 100644 --- a/src/interdiff.c +++ b/src/interdiff.c @@ -1661,6 +1661,15 @@ remove_line (struct lines_info *lines, const char *line, } } + if (!kill) { + /* The line we were asked to remove is not present (for + * example when the two patches do not commute). There is + * nothing to do. */ + if (debug) + printf ("Nothing to remove at %lu: %s", n, line); + return; + } + at = kill; while (at) { at->n--; diff --git a/tests/flip20/run-test b/tests/flip20/run-test new file mode 100755 index 0000000..85c5e08 --- /dev/null +++ b/tests/flip20/run-test @@ -0,0 +1,30 @@ +#!/bin/sh + +# This is a flipdiff(1) testcase. +# Test: non-commuting patches where the second patch removes a line that +# the first patch had added. flipdiff used to crash on this input. + + +. ${top_srcdir-.}/tests/common.sh + +cat << EOF > file.orig +a +b +EOF + +cat << EOF > file +a-m +b-y +EOF + +${DIFF} -u file.orig file > patch1 + +mv -f file file.orig +cat << EOF > file +a +b-y +EOF + +${DIFF} -u file.orig file > patch2 + +${FLIPDIFF} patch1 patch2 > patch-flipped || exit 1