internal/span: fix off-by-one in ToUTF16Column

Change-Id: I8c8344046b13f2606d7257ef8632e0426e15a85b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/173498
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/internal/span/utf16.go b/internal/span/utf16.go
index 4439acb..887e3be 100644
--- a/internal/span/utf16.go
+++ b/internal/span/utf16.go
@@ -36,12 +36,12 @@
 		return -1, fmt.Errorf("ToUTF16Column: offsets %v-%v outside file contents (%v)", lineOffset, offset, len(content))
 	}
 	// Use the offset to pick out the line start.
-	// This cannot panic:  offset > len(content) and lineOffset < offset.
+	// This cannot panic: offset > len(content) and lineOffset < offset.
 	start := content[lineOffset:]
 
 	// Now, truncate down to the supplied column.
-	if col >= len(start) {
-		return -1, fmt.Errorf("ToUTF16Column: line (%v) is shorter than column (%v)", len(start), col)
+	if col > len(start) { // col is 1-indexed
+		return -1, fmt.Errorf("ToUTF16Column: length of line (%v) is less than column (%v)", len(start), col)
 	}
 	start = start[:col]
 	// and count the number of utf16 characters
diff --git a/internal/span/utf16_test.go b/internal/span/utf16_test.go
index 3a3b659..5f97108 100644
--- a/internal/span/utf16_test.go
+++ b/internal/span/utf16_test.go
@@ -27,7 +27,7 @@
 	c := span.NewContentConverter("test", input)
 	for line := 1; line <= 9; line++ {
 		runeColumn, runeChr := 0, 0
-		for chr := 1; chr <= 9; chr++ {
+		for chr := 1; chr <= 10; chr++ {
 			switch {
 			case chr <= line:
 				runeChr = chr
@@ -67,3 +67,28 @@
 		}
 	}
 }
+
+func TestUTF16Errors(t *testing.T) {
+	var input = []byte(`
+hello
+world
+`)[1:]
+	for _, test := range []struct {
+		line, col, offset int
+		want              string
+	}{
+		{
+			1, 6, 12,
+			"ToUTF16Column: length of line (5) is less than column (6)",
+		},
+		{
+			1, 6, 13,
+			"ToUTF16Column: offsets 8-13 outside file contents (12)",
+		},
+	} {
+		p := span.NewPoint(test.line, test.col, test.offset)
+		if _, err := span.ToUTF16Column(p, input); err == nil || err.Error() != test.want {
+			t.Errorf("expected %v, got %v", test.want, err)
+		}
+	}
+}