diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-12 01:31:45 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-12 01:31:45 +0000 |
commit | 9a0e3259f44ad2de9c65f14f756dab01b3598391 (patch) | |
tree | 86a3b8019380d5fad53258c4baba3dd9e1e7c736 /libgo/go/fmt | |
parent | c6135f063335419e4b5df0b4e1caf145882c8a4b (diff) | |
download | gcc-9a0e3259f44ad2de9c65f14f756dab01b3598391.zip gcc-9a0e3259f44ad2de9c65f14f756dab01b3598391.tar.gz gcc-9a0e3259f44ad2de9c65f14f756dab01b3598391.tar.bz2 |
libgo: Update to weekly.2011-12-14.
From-SVN: r183118
Diffstat (limited to 'libgo/go/fmt')
-rw-r--r-- | libgo/go/fmt/fmt_test.go | 34 | ||||
-rw-r--r-- | libgo/go/fmt/format.go | 4 | ||||
-rw-r--r-- | libgo/go/fmt/print.go | 7 | ||||
-rw-r--r-- | libgo/go/fmt/scan_test.go | 12 |
4 files changed, 50 insertions, 7 deletions
diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go index 63c3338..d7fe296 100644 --- a/libgo/go/fmt/fmt_test.go +++ b/libgo/go/fmt/fmt_test.go @@ -813,3 +813,37 @@ func TestPanics(t *testing.T) { } } } + +// Test that erroneous String routine doesn't cause fatal recursion. +var recurCount = 0 + +type Recur struct { + i int + failed *bool +} + +func (r Recur) String() string { + if recurCount++; recurCount > 10 { + *r.failed = true + return "FAIL" + } + // This will call badVerb. Before the fix, that would cause us to recur into + // this routine to print %!p(value). Now we don't call the user's method + // during an error. + return Sprintf("recur@%p value: %d", r, r.i) +} + +func TestBadVerbRecursion(t *testing.T) { + failed := false + r := Recur{3, &failed} + Sprintf("recur@%p value: %d\n", &r, r.i) + if failed { + t.Error("fail with pointer") + } + failed = false + r = Recur{4, &failed} + Sprintf("recur@%p, value: %d\n", r, r.i) + if failed { + t.Error("fail with value") + } +} diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go index fbafa9d..5f62c06 100644 --- a/libgo/go/fmt/format.go +++ b/libgo/go/fmt/format.go @@ -331,9 +331,9 @@ func (f *fmt) fmt_q(s string) { func (f *fmt) fmt_qc(c int64) { var quoted string if f.plus { - quoted = strconv.QuoteRuneToASCII(int(c)) + quoted = strconv.QuoteRuneToASCII(rune(c)) } else { - quoted = strconv.QuoteRune(int(c)) + quoted = strconv.QuoteRune(rune(c)) } f.padString(quoted) } diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go index 8b15a82..9f157da 100644 --- a/libgo/go/fmt/print.go +++ b/libgo/go/fmt/print.go @@ -74,6 +74,7 @@ type GoStringer interface { type pp struct { n int panicking bool + erroring bool // printing an error condition buf bytes.Buffer // field holds the current item, as an interface{}. field interface{} @@ -124,6 +125,7 @@ var ppFree = newCache(func() interface{} { return new(pp) }) func newPrinter() *pp { p := ppFree.get().(*pp) p.panicking = false + p.erroring = false p.fmt.init(&p.buf) return p } @@ -299,6 +301,7 @@ func (p *pp) unknownType(v interface{}) { } func (p *pp) badVerb(verb rune) { + p.erroring = true p.add('%') p.add('!') p.add(verb) @@ -316,6 +319,7 @@ func (p *pp) badVerb(verb rune) { p.buf.Write(nilAngleBytes) } p.add(')') + p.erroring = false } func (p *pp) fmtBool(v bool, verb rune) { @@ -606,6 +610,9 @@ func (p *pp) catchPanic(field interface{}, verb rune) { } func (p *pp) handleMethods(verb rune, plus, goSyntax bool, depth int) (wasString, handled bool) { + if p.erroring { + return + } // Is it a Formatter? if formatter, ok := p.field.(Formatter); ok { handled = true diff --git a/libgo/go/fmt/scan_test.go b/libgo/go/fmt/scan_test.go index 0689bf3..b26c828 100644 --- a/libgo/go/fmt/scan_test.go +++ b/libgo/go/fmt/scan_test.go @@ -56,6 +56,7 @@ var ( stringVal string stringVal1 string bytesVal []byte + runeVal rune complex64Val complex64 complex128Val complex128 renamedBoolVal renamedBool @@ -225,9 +226,9 @@ var scanfTests = []ScanfTest{ {"%v", "0377\n", &intVal, 0377}, {"%v", "0x44\n", &intVal, 0x44}, {"%d", "72\n", &intVal, 72}, - {"%c", "a\n", &intVal, 'a'}, - {"%c", "\u5072\n", &intVal, 0x5072}, - {"%c", "\u1234\n", &intVal, '\u1234'}, + {"%c", "a\n", &runeVal, 'a'}, + {"%c", "\u5072\n", &runeVal, '\u5072'}, + {"%c", "\u1234\n", &runeVal, '\u1234'}, {"%d", "73\n", &int8Val, int8(73)}, {"%d", "+74\n", &int16Val, int16(74)}, {"%d", "75\n", &int32Val, int32(75)}, @@ -322,6 +323,7 @@ var s, t string var c complex128 var x, y Xs var z IntString +var r1, r2, r3 rune var multiTests = []ScanfMultiTest{ {"", "", []interface{}{}, []interface{}{}, ""}, @@ -333,7 +335,7 @@ var multiTests = []ScanfMultiTest{ {"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""}, {"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""}, {"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""}, - {"%c%c%c", "2\u50c2X", args(&i, &j, &k), args('2', '\u50c2', 'X'), ""}, + {"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""}, // Custom scanners. {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""}, @@ -347,7 +349,7 @@ var multiTests = []ScanfMultiTest{ {"X%d", "10X", args(&intVal), nil, "input does not match format"}, // Bad UTF-8: should see every byte. - {"%c%c%c", "\xc2X\xc2", args(&i, &j, &k), args(utf8.RuneError, 'X', utf8.RuneError), ""}, + {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""}, } func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) { |