diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-06-06 22:37:27 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2014-06-06 22:37:27 +0000 |
commit | 6736ef96eab222e58e6294f42be981a5afb59811 (patch) | |
tree | 2bc668fae9bf96f9a3988e0b0a16685bde8c4f0b /libgo/go/text | |
parent | 38a138411da4206c53f9a153ee9c3624fce58a52 (diff) | |
download | gcc-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.go | 14 | ||||
-rw-r--r-- | libgo/go/text/tabwriter/tabwriter.go | 12 | ||||
-rw-r--r-- | libgo/go/text/tabwriter/tabwriter_test.go | 37 | ||||
-rw-r--r-- | libgo/go/text/template/exec.go | 3 | ||||
-rw-r--r-- | libgo/go/text/template/exec_test.go | 30 |
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 |