aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/text
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2014-06-06 22:37:27 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2014-06-06 22:37:27 +0000
commit6736ef96eab222e58e6294f42be981a5afb59811 (patch)
tree2bc668fae9bf96f9a3988e0b0a16685bde8c4f0b /libgo/go/text
parent38a138411da4206c53f9a153ee9c3624fce58a52 (diff)
downloadgcc-6736ef96eab222e58e6294f42be981a5afb59811.zip
gcc-6736ef96eab222e58e6294f42be981a5afb59811.tar.gz
gcc-6736ef96eab222e58e6294f42be981a5afb59811.tar.bz2
libgo: Merge to master revision 19184.
The next revision, 19185, renames several runtime files, and will be handled in a separate change. From-SVN: r211328
Diffstat (limited to 'libgo/go/text')
-rw-r--r--libgo/go/text/scanner/scanner_test.go14
-rw-r--r--libgo/go/text/tabwriter/tabwriter.go12
-rw-r--r--libgo/go/text/tabwriter/tabwriter_test.go37
-rw-r--r--libgo/go/text/template/exec.go3
-rw-r--r--libgo/go/text/template/exec_test.go30
5 files changed, 74 insertions, 22 deletions
diff --git a/libgo/go/text/scanner/scanner_test.go b/libgo/go/text/scanner/scanner_test.go
index 496eed4..086ab56 100644
--- a/libgo/go/text/scanner/scanner_test.go
+++ b/libgo/go/text/scanner/scanner_test.go
@@ -360,7 +360,7 @@ func TestScanSelectedMask(t *testing.T) {
func TestScanNext(t *testing.T) {
const BOM = '\uFEFF'
BOMs := string(BOM)
- s := new(Scanner).Init(bytes.NewBufferString(BOMs + "if a == bcd /* com" + BOMs + "ment */ {\n\ta += c\n}" + BOMs + "// line comment ending in eof"))
+ s := new(Scanner).Init(strings.NewReader(BOMs + "if a == bcd /* com" + BOMs + "ment */ {\n\ta += c\n}" + BOMs + "// line comment ending in eof"))
checkTok(t, s, 1, s.Scan(), Ident, "if") // the first BOM is ignored
checkTok(t, s, 1, s.Scan(), Ident, "a")
checkTok(t, s, 1, s.Scan(), '=', "=")
@@ -402,7 +402,7 @@ func TestScanWhitespace(t *testing.T) {
}
func testError(t *testing.T, src, pos, msg string, tok rune) {
- s := new(Scanner).Init(bytes.NewBufferString(src))
+ s := new(Scanner).Init(strings.NewReader(src))
errorCalled := false
s.Error = func(s *Scanner, m string) {
if !errorCalled {
@@ -491,13 +491,13 @@ func checkScanPos(t *testing.T, s *Scanner, offset, line, column int, char rune)
func TestPos(t *testing.T) {
// corner case: empty source
- s := new(Scanner).Init(bytes.NewBufferString(""))
+ s := new(Scanner).Init(strings.NewReader(""))
checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
s.Peek() // peek doesn't affect the position
checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
// corner case: source with only a newline
- s = new(Scanner).Init(bytes.NewBufferString("\n"))
+ s = new(Scanner).Init(strings.NewReader("\n"))
checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
checkNextPos(t, s, 1, 2, 1, '\n')
// after EOF position doesn't change
@@ -509,7 +509,7 @@ func TestPos(t *testing.T) {
}
// corner case: source with only a single character
- s = new(Scanner).Init(bytes.NewBufferString("本"))
+ s = new(Scanner).Init(strings.NewReader("本"))
checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
checkNextPos(t, s, 3, 1, 2, '本')
// after EOF position doesn't change
@@ -521,7 +521,7 @@ func TestPos(t *testing.T) {
}
// positions after calling Next
- s = new(Scanner).Init(bytes.NewBufferString(" foo६४ \n\n本語\n"))
+ s = new(Scanner).Init(strings.NewReader(" foo६४ \n\n本語\n"))
checkNextPos(t, s, 1, 1, 2, ' ')
s.Peek() // peek doesn't affect the position
checkNextPos(t, s, 2, 1, 3, ' ')
@@ -546,7 +546,7 @@ func TestPos(t *testing.T) {
}
// positions after calling Scan
- s = new(Scanner).Init(bytes.NewBufferString("abc\n本語\n\nx"))
+ s = new(Scanner).Init(strings.NewReader("abc\n本語\n\nx"))
s.Mode = 0
s.Whitespace = 0
checkScanPos(t, s, 0, 1, 1, 'a')
diff --git a/libgo/go/text/tabwriter/tabwriter.go b/libgo/go/text/tabwriter/tabwriter.go
index 722ac8d..c0c32d5 100644
--- a/libgo/go/text/tabwriter/tabwriter.go
+++ b/libgo/go/text/tabwriter/tabwriter.go
@@ -434,9 +434,13 @@ func (b *Writer) terminateCell(htab bool) int {
return len(*line)
}
-func handlePanic(err *error) {
+func handlePanic(err *error, op string) {
if e := recover(); e != nil {
- *err = e.(osError).err // re-panics if it's not a local osError
+ if nerr, ok := e.(osError); ok {
+ *err = nerr.err
+ return
+ }
+ panic("tabwriter: panic during " + op)
}
}
@@ -447,7 +451,7 @@ func handlePanic(err *error) {
//
func (b *Writer) Flush() (err error) {
defer b.reset() // even in the presence of errors
- defer handlePanic(&err)
+ defer handlePanic(&err, "Flush")
// add current cell if not empty
if b.cell.size > 0 {
@@ -471,7 +475,7 @@ var hbar = []byte("---\n")
// while writing to the underlying output stream.
//
func (b *Writer) Write(buf []byte) (n int, err error) {
- defer handlePanic(&err)
+ defer handlePanic(&err, "Write")
// split text into cells
n = 0
diff --git a/libgo/go/text/tabwriter/tabwriter_test.go b/libgo/go/text/tabwriter/tabwriter_test.go
index b0526a0..9d3111e 100644
--- a/libgo/go/text/tabwriter/tabwriter_test.go
+++ b/libgo/go/text/tabwriter/tabwriter_test.go
@@ -613,3 +613,40 @@ func Test(t *testing.T) {
check(t, e.testname, e.minwidth, e.tabwidth, e.padding, e.padchar, e.flags, e.src, e.expected)
}
}
+
+type panicWriter struct{}
+
+func (panicWriter) Write([]byte) (int, error) {
+ panic("cannot write")
+}
+
+func wantPanicString(t *testing.T, want string) {
+ if e := recover(); e != nil {
+ got, ok := e.(string)
+ switch {
+ case !ok:
+ t.Errorf("got %v (%T), want panic string", e, e)
+ case got != want:
+ t.Errorf("wrong panic message: got %q, want %q", got, want)
+ }
+ }
+}
+
+func TestPanicDuringFlush(t *testing.T) {
+ defer wantPanicString(t, "tabwriter: panic during Flush")
+ var p panicWriter
+ w := new(Writer)
+ w.Init(p, 0, 0, 5, ' ', 0)
+ io.WriteString(w, "a")
+ w.Flush()
+ t.Errorf("failed to panic during Flush")
+}
+
+func TestPanicDuringWrite(t *testing.T) {
+ defer wantPanicString(t, "tabwriter: panic during Write")
+ var p panicWriter
+ w := new(Writer)
+ w.Init(p, 0, 0, 5, ' ', 0)
+ io.WriteString(w, "a\n\n") // the second \n triggers a call to w.Write and thus a panic
+ t.Errorf("failed to panic during Write")
+}
diff --git a/libgo/go/text/template/exec.go b/libgo/go/text/template/exec.go
index 43b0b26..6de37a1 100644
--- a/libgo/go/text/template/exec.go
+++ b/libgo/go/text/template/exec.go
@@ -594,6 +594,9 @@ func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Valu
switch {
case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ):
value = value.Elem()
+ if !value.IsValid() {
+ s.errorf("dereference of nil pointer of type %s", typ)
+ }
case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
value = value.Addr()
default:
diff --git a/libgo/go/text/template/exec_test.go b/libgo/go/text/template/exec_test.go
index f60702d..868f2cb 100644
--- a/libgo/go/text/template/exec_test.go
+++ b/libgo/go/text/template/exec_test.go
@@ -512,6 +512,8 @@ var execTests = []execTest{
{"bug9", "{{.cause}}", "neglect", map[string]string{"cause": "neglect"}, true},
// Field chain starting with function did not work.
{"bug10", "{{mapOfThree.three}}-{{(mapOfThree).three}}", "3-3", 0, true},
+ // Dereferencing nil pointer while evaluating function arguments should not panic. Issue 7333.
+ {"bug11", "{{valueString .PS}}", "", T{}, false},
}
func zeroArgs() string {
@@ -546,6 +548,11 @@ func vfunc(V, *V) string {
return "vfunc"
}
+// valueString takes a string, not a pointer.
+func valueString(v string) string {
+ return "value is ignored"
+}
+
func add(args ...int) int {
sum := 0
for _, x := range args {
@@ -580,17 +587,18 @@ func mapOfThree() interface{} {
func testExecute(execTests []execTest, template *Template, t *testing.T) {
b := new(bytes.Buffer)
funcs := FuncMap{
- "add": add,
- "count": count,
- "dddArg": dddArg,
- "echo": echo,
- "makemap": makemap,
- "mapOfThree": mapOfThree,
- "oneArg": oneArg,
- "stringer": stringer,
- "typeOf": typeOf,
- "vfunc": vfunc,
- "zeroArgs": zeroArgs,
+ "add": add,
+ "count": count,
+ "dddArg": dddArg,
+ "echo": echo,
+ "makemap": makemap,
+ "mapOfThree": mapOfThree,
+ "oneArg": oneArg,
+ "stringer": stringer,
+ "typeOf": typeOf,
+ "valueString": valueString,
+ "vfunc": vfunc,
+ "zeroArgs": zeroArgs,
}
for _, test := range execTests {
var tmpl *Template