From 9133ab55d05669b46e2e7002f23ad42bccb9ae12 Mon Sep 17 00:00:00 2001 From: "Luke I. Wilson" Date: Wed, 24 Mar 2021 11:40:18 -0500 Subject: [PATCH] Bounds check delete regions in rope buffer --- ui/buffer/rope.go | 12 +++++++++++- ui/buffer/rope_test.go | 19 ++++++++++++++++--- ui/textedit.go | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/ui/buffer/rope.go b/ui/buffer/rope.go index f8855ce..9d9a2f2 100644 --- a/ui/buffer/rope.go +++ b/ui/buffer/rope.go @@ -114,7 +114,17 @@ func (b *RopeBuffer) Insert(line, col int, value []byte) { // Remove deletes any characters between startLine, startCol, and endLine, // endCol, inclusive bounds. func (b *RopeBuffer) Remove(startLine, startCol, endLine, endCol int) { - (*rope.Node)(b).Remove(b.pos(startLine, startCol), b.pos(endLine, endCol)+1) + start := b.pos(startLine, startCol) + end := b.pos(endLine, endCol) + 1 + + if len := (*rope.Node)(b).Len(); end >= len { + end = len + if start > end { + start = end + } + } + + (*rope.Node)(b).Remove(start, end) } // Returns the number of occurrences of 'sequence' in the buffer, within the range diff --git a/ui/buffer/rope_test.go b/ui/buffer/rope_test.go index 0b3d46c..5a8e14b 100644 --- a/ui/buffer/rope_test.go +++ b/ui/buffer/rope_test.go @@ -4,16 +4,29 @@ import "testing" func TestRopeInserting(t *testing.T) { var buf Buffer = NewRopeBuffer([]byte("some")) - buf.Insert(0, 4, []byte(" text")) // Insert " text" after "some" + buf.Insert(0, 4, []byte(" text\n")) // Insert " text" after "some" buf.Insert(0, 0, []byte("with\n\t")) - // "with\n\tsome text" + //with + // some text + // buf.Remove(0, 4, 1, 5) // Delete from line 0, col 4, to line 1, col 6 "\n\tsome " - if str := string(buf.Bytes()); str != "withtext" { + if str := string(buf.Bytes()); str != "withtext\n" { t.Errorf("string does not match \"withtext\", got %#v", str) t.Fail() } + + //withtext + // + + // Note the inclusive bounds and pointing to last line, first column. + buf.Remove(0, 0, 1, 0) // Delete all of the buffer + + if str := string(buf.Bytes()); str != "" { + t.Errorf("string does not math \"\", got %#v", str) + t.Fail() + } } func TestRopeBounds(t *testing.T) { diff --git a/ui/textedit.go b/ui/textedit.go index cc0419a..a3faebd 100644 --- a/ui/textedit.go +++ b/ui/textedit.go @@ -302,6 +302,7 @@ func (t *TextEdit) getColumnWidth() int { // If the returned string is empty, then nothing was selected. The slice returned may or may not // be a copy of the buffer, so do not write to it. func (t *TextEdit) GetSelectedBytes() []byte { + // TODO: there's a bug with copying text if t.selectMode { return t.Buffer.Slice(t.selection.StartLine, t.selection.StartCol, t.selection.EndLine, t.selection.EndCol) }