fiddle - Fix crash when exceeding slice bounds.

Bug: skia:
Change-Id: If7f10ce22e6e08b4d1db6f3d6eca4c7c71667cd6
Reviewed-on: https://skia-review.googlesource.com/c/177028
Reviewed-by: Ravi Mistry <rmistry@google.com>
Commit-Queue: Joe Gregorio <jcgregorio@google.com>
diff --git a/fiddlek/go/fiddler/main.go b/fiddlek/go/fiddler/main.go
index ef77af9..6a7af25 100644
--- a/fiddlek/go/fiddler/main.go
+++ b/fiddlek/go/fiddler/main.go
@@ -258,13 +258,6 @@
 	return base64.StdEncoding.EncodeToString(b)
 }
 
-func trunc(s string) string {
-	if len(s) < 100 {
-		return s
-	}
-	return s[:100] + "..."
-}
-
 // createWebm runs ffmpeg over the images in the given dir.
 func createWebm(ctx context.Context, prefix, tmpDir string) error {
 	// ffmpeg -r $FPS -pattern_type glob -i '*.png' -c:v libvpx-vp9 -lossless 1 output.webm
@@ -284,7 +277,7 @@
 		CombinedOutput: output,
 	}
 	if err := exec.Run(ctx, runCmd); err != nil {
-		return fmt.Errorf("ffmpeg failed %#v %q: %s", *runCmd, trunc(output.String()), err)
+		return fmt.Errorf("ffmpeg failed %#v %q: %s", *runCmd, util.Trunc(output.String(), 100), err)
 	}
 
 	return nil
diff --git a/fiddlek/go/runner/runner.go b/fiddlek/go/runner/runner.go
index 6cf4097..22b7635 100644
--- a/fiddlek/go/runner/runner.go
+++ b/fiddlek/go/runner/runner.go
@@ -215,7 +215,7 @@
 	if n == types.MAX_JSON_SIZE {
 		return nil, fmt.Errorf("Response too large, truncated at %d bytes.", n)
 	}
-	sklog.Infof("Got response: %q", output.String()[:20])
+	sklog.Infof("Got response: %q", util.Trunc(output.String(), 20))
 	if err != nil {
 		return nil, fmt.Errorf("Failed to read response: %s", err)
 	}
diff --git a/go/util/util.go b/go/util/util.go
index 883be03..7a00c8c 100644
--- a/go/util/util.go
+++ b/go/util/util.go
@@ -118,6 +118,16 @@
 	return false
 }
 
+// Trunc returns s truncated to n+3 chars.
+//
+// If len(s) < n then the string is unchanged.
+func Trunc(s string, n int) string {
+	if len(s) <= n {
+		return s
+	}
+	return s[:n] + "..."
+}
+
 // ContainsAny returns true if |s| contains any element of |a|.
 func ContainsAny(s string, a []string) bool {
 	for _, x := range a {
diff --git a/go/util/util_test.go b/go/util/util_test.go
index 7db772f..1794127 100644
--- a/go/util/util_test.go
+++ b/go/util/util_test.go
@@ -912,3 +912,12 @@
 		test(int32(i), int32(i))
 	}
 }
+
+func TestTrunc(t *testing.T) {
+	testutils.SmallTest(t)
+
+	assert.Equal(t, "foo...", Trunc("foobar", 3))
+	assert.Equal(t, "fooba...", Trunc("foobar", 5))
+	assert.Equal(t, "foobar", Trunc("foobar", 6))
+	assert.Equal(t, "foobar", Trunc("foobar", 7))
+}