From 700129d07948cac9f5529e9889beb99778532181 Mon Sep 17 00:00:00 2001 From: Joel Christner Date: Mon, 1 Jun 2026 16:01:29 -0700 Subject: [PATCH 1/3] Clamp selection text bounds --- src/XTerm.NET.Tests/SelectionTests.cs | 26 +++++++++++++++++++++ src/XTerm.NET/Selection/SelectionManager.cs | 7 ++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/XTerm.NET.Tests/SelectionTests.cs b/src/XTerm.NET.Tests/SelectionTests.cs index 777470c..6cf02da 100644 --- a/src/XTerm.NET.Tests/SelectionTests.cs +++ b/src/XTerm.NET.Tests/SelectionTests.cs @@ -68,6 +68,32 @@ public void SelectAll_IncludesScrollback_NotJustViewport() Assert.Contains("Line7", selectedText); } + [Fact] + public void SelectionText_ClampsNegativeColumns() + { + var terminal = new Terminal(new TerminalOptions { Rows = 3, Cols = 10, Scrollback = 20 }); + terminal.Write("alpha"); + + terminal.Selection.StartSelection(-3, 0); + terminal.Selection.UpdateSelection(4, 0); + terminal.Selection.EndSelection(); + + Assert.Equal("alpha", terminal.Selection.GetSelectionText()); + } + + [Fact] + public void SelectionText_ClampsColumnsPastRightEdge() + { + var terminal = new Terminal(new TerminalOptions { Rows = 3, Cols = 10, Scrollback = 20 }); + terminal.Write("alpha"); + + terminal.Selection.StartSelection(0, 0); + terminal.Selection.UpdateSelection(30, 0); + terminal.Selection.EndSelection(); + + Assert.StartsWith("alpha", terminal.Selection.GetSelectionText()); + } + [Fact] public void Selection_IsCleared_WhenTrimRemovesSelectedLines() { diff --git a/src/XTerm.NET/Selection/SelectionManager.cs b/src/XTerm.NET/Selection/SelectionManager.cs index 0cdfea3..953578c 100644 --- a/src/XTerm.NET/Selection/SelectionManager.cs +++ b/src/XTerm.NET/Selection/SelectionManager.cs @@ -145,8 +145,11 @@ public string GetSelectionText() if (line == null) continue; - int startX = (y == start.y) ? start.x : 0; - int endX = (y == end.y) ? end.x : _terminal.Cols - 1; + int startX = Math.Clamp((y == start.y) ? start.x : 0, 0, _terminal.Cols - 1); + int endX = Math.Clamp((y == end.y) ? end.x : _terminal.Cols - 1, 0, _terminal.Cols - 1); + + if (startX > endX) + continue; var lineText = line.TranslateToString(false, startX, endX + 1); text.Append(lineText); From 334b819e2fc79257f66882c43bb6dd79bbd08cbf Mon Sep 17 00:00:00 2001 From: Joel Christner Date: Sun, 21 Jun 2026 09:16:39 -0700 Subject: [PATCH 2/3] Handle zero-column selection text --- src/XTerm.NET.Tests/SelectionTests.cs | 12 ++++++++++++ src/XTerm.NET/Selection/SelectionManager.cs | 8 ++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/XTerm.NET.Tests/SelectionTests.cs b/src/XTerm.NET.Tests/SelectionTests.cs index 6cf02da..2115c23 100644 --- a/src/XTerm.NET.Tests/SelectionTests.cs +++ b/src/XTerm.NET.Tests/SelectionTests.cs @@ -94,6 +94,18 @@ public void SelectionText_ClampsColumnsPastRightEdge() Assert.StartsWith("alpha", terminal.Selection.GetSelectionText()); } + [Fact] + public void SelectionText_ReturnsEmpty_WhenTerminalHasNoColumns() + { + var terminal = new Terminal(new TerminalOptions { Rows = 3, Cols = 0, Scrollback = 20 }); + + terminal.Selection.StartSelection(0, 0); + terminal.Selection.UpdateSelection(0, 0); + terminal.Selection.EndSelection(); + + Assert.Equal(string.Empty, terminal.Selection.GetSelectionText()); + } + [Fact] public void Selection_IsCleared_WhenTrimRemovesSelectedLines() { diff --git a/src/XTerm.NET/Selection/SelectionManager.cs b/src/XTerm.NET/Selection/SelectionManager.cs index 953578c..98973a1 100644 --- a/src/XTerm.NET/Selection/SelectionManager.cs +++ b/src/XTerm.NET/Selection/SelectionManager.cs @@ -145,8 +145,12 @@ public string GetSelectionText() if (line == null) continue; - int startX = Math.Clamp((y == start.y) ? start.x : 0, 0, _terminal.Cols - 1); - int endX = Math.Clamp((y == end.y) ? end.x : _terminal.Cols - 1, 0, _terminal.Cols - 1); + int lastColumn = _terminal.Cols - 1; + if (lastColumn < 0) + continue; + + int startX = Math.Clamp((y == start.y) ? start.x : 0, 0, lastColumn); + int endX = Math.Clamp((y == end.y) ? end.x : lastColumn, 0, lastColumn); if (startX > endX) continue; From 948a3e5002760dffec732b25ea7814818b5fb4a6 Mon Sep 17 00:00:00 2001 From: Tom Laird-McConnell Date: Mon, 22 Jun 2026 10:15:47 -0700 Subject: [PATCH 3/3] Fix formatting in SelectionTests.cs --- src/XTerm.NET.Tests/SelectionTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/XTerm.NET.Tests/SelectionTests.cs b/src/XTerm.NET.Tests/SelectionTests.cs index 726c06b..28b0254 100644 --- a/src/XTerm.NET.Tests/SelectionTests.cs +++ b/src/XTerm.NET.Tests/SelectionTests.cs @@ -104,6 +104,8 @@ public void SelectionText_ReturnsEmpty_WhenTerminalHasNoColumns() terminal.Selection.EndSelection(); Assert.Equal(string.Empty, terminal.Selection.GetSelectionText()); + } + public void SelectionText_UsesLineFeedLineEndings() { var terminal = new Terminal(new TerminalOptions { Rows = 3, Cols = 80, Scrollback = 20 });