aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2010-10-13 17:12:43 -0700
committerRob Pike <r@golang.org>2010-10-13 17:12:43 -0700
commit52e3c99cfb32e5ff91a2a15d506d2148af8fc813 (patch)
tree155e3e6d47260f8c1685e5897d828bd84a3f4d17
parentd6df3017749bbe4737789c381b50ef71eb11b900 (diff)
downloadgo-52e3c99cfb32e5ff91a2a15d506d2148af8fc813.tar.gz
go-52e3c99cfb32e5ff91a2a15d506d2148af8fc813.zip
bufio: bulletproof UnreadRune
After a fill(), there is nothing to back up. Make sure UnreadRune recognizes the situation. Fixes #1137. (Stops the crash, but doesn't make UnreadRune usable after a Peek()). R=rsc CC=golang-dev https://golang.org/cl/2498041
-rw-r--r--src/pkg/bufio/bufio.go2
-rw-r--r--src/pkg/bufio/bufio_test.go9
2 files changed, 10 insertions, 1 deletions
diff --git a/src/pkg/bufio/bufio.go b/src/pkg/bufio/bufio.go
index 8c951903a1..70caf5dae8 100644
--- a/src/pkg/bufio/bufio.go
+++ b/src/pkg/bufio/bufio.go
@@ -226,7 +226,7 @@ func (b *Reader) ReadRune() (rune int, size int, err os.Error) {
// regard it is stricter than UnreadByte, which will unread the last byte
// from any read operation.)
func (b *Reader) UnreadRune() os.Error {
- if b.lastRuneSize < 0 {
+ if b.lastRuneSize < 0 || b.r == 0 {
return ErrInvalidUnreadRune
}
b.r -= b.lastRuneSize
diff --git a/src/pkg/bufio/bufio_test.go b/src/pkg/bufio/bufio_test.go
index fb0ed045ae..fe04b91691 100644
--- a/src/pkg/bufio/bufio_test.go
+++ b/src/pkg/bufio/bufio_test.go
@@ -564,3 +564,12 @@ func TestPeek(t *testing.T) {
t.Fatalf("want EOF got %v", err)
}
}
+
+func TestPeekThenUnreadRune(t *testing.T) {
+ // This sequence used to cause a crash.
+ r := NewReader(strings.NewReader("x"))
+ r.ReadRune()
+ r.Peek(1)
+ r.UnreadRune()
+ r.ReadRune() // Used to panic here
+}