From 4d51143eec019f1fb5bc3101baf417945f93e2b4 Mon Sep 17 00:00:00 2001 From: Paul Melekhov Date: Tue, 25 Aug 2026 04:50:00 +0500 Subject: [PATCH] Fix reverse overlap handling in line mode --- src/Diff.php | 2 +- tests/DiffTest.php | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Diff.php b/src/Diff.php index c425b75..afa0ca7 100644 --- a/src/Diff.php +++ b/src/Diff.php @@ -550,7 +550,7 @@ public function cleanupSemantic() ))); $diffs[$pointer - 1] = array( self::INSERT, - mb_substr($insertion, 0, $overlap_length2), + mb_substr($insertion, 0, -$overlap_length2), ); $diffs[$pointer + 1] = array( self::DELETE, diff --git a/tests/DiffTest.php b/tests/DiffTest.php index 5fc6fa8..e34be9a 100644 --- a/tests/DiffTest.php +++ b/tests/DiffTest.php @@ -443,6 +443,19 @@ public function testCleanupSemantic() ), $this->d->getChanges()); } + public function testLineModePreservesTextsAfterReverseOverlap() + { + $overlap = str_repeat('x', Diff::LINEMODE_THRESOLD - 2); + $source = $overlap . 'old'; + $destination = 'new' . $overlap; + + // Skip half-match so the smallest possible input reaches line-mode. + $this->d->setTimeout(0)->main($source, $destination, true); + + $this->assertSame($source, $this->d->text1()); + $this->assertSame($destination, $this->d->text2()); + } + public function testCleanupEfficiency() { // Cleanup operationally trivial equalities.