Skip to content

bug(ansi): Truncate, TruncateLeft etc do not obey length in many cases #541

@lrstanley

Description

@lrstanley

Describe the bug

In many cases, Truncate, TruncateLeft, and potentially other functions do not obey the provided length, at least lengths that get returned by StringWidth.

To Reproduce

Use the following patch to add fuzzing for Truncate and TruncateLeft:

diff --git a/ansi/truncate_test.go b/ansi/truncate_test.go
index decf11a..17e5ba3 100644
--- a/ansi/truncate_test.go
+++ b/ansi/truncate_test.go
@@ -1,6 +1,7 @@
 package ansi
 
 import (
+       "math/rand"
        "testing"
 )
 
@@ -458,3 +459,35 @@ func TestByteToGraphemeRange(t *testing.T) {
                })
        }
 }
+
+func FuzzTruncate(f *testing.F) {
+       for _, tc := range tcases {
+               f.Add(tc.input)
+       }
+
+       f.Fuzz(func(t *testing.T, input string) {
+               n := rand.Intn(100) + 1
+               result := Truncate(input, n, "…")
+               w := StringWidth(result)
+
+               if w > n {
+                       t.Errorf("expected width to be no greater than %d, got %d", n, w)
+               }
+       })
+}
+
+func FuzzTruncateLeft(f *testing.F) {
+       for _, tc := range tcases {
+               f.Add(tc.input)
+       }
+
+       f.Fuzz(func(t *testing.T, input string) {
+               n := rand.Intn(100) + 1
+               result := TruncateLeft(input, n, "…")
+               w := StringWidth(result)
+
+               if w > n {
+                       t.Errorf("expected width to be no greater than %d, got %d", n, w)
+               }
+       })
+}

And run with:

$ go test -run=".*" -fuzz="^FuzzTruncate$" ./ansi/
# or
$ go test -run=".*" -fuzz="^FuzzTruncateLeft$" ./ansi/

I get failures nearly instantly. An example of 1:

string("\x9f \xec؋\xf00")

Expected behavior

The above fuzzing methods simply check to see if the resulting output from either function is ever longer (according to ansi.StringWidth()) than the provided max length passed to the associated function. I would expect that the result to always be truncated and never exceed the length provided as the input, at least according to the "length" that ansi.StringWidth() also calculates.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions