summaryrefslogtreecommitdiff
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
commitffa772e46c8dc5b16738f476f838f56db2d1268a (patch)
treec32fc2a125bbe8b697ed25978ff2d031eb41e0a8
parent2ce6b6dce19f19271917455f2f2277203dd3d3db (diff)
downloadgo-ffa772e46c8dc5b16738f476f838f56db2d1268a.tar.gz
bufio: bulletproof UnreadRune
After a fill(), there is nothing to back up. Make sure UnreadRune recognizes the situation. Fixes issue 1137. (Stops the crash, but doesn't make UnreadRune usable after a Peek()). R=rsc CC=golang-dev http://codereview.appspot.com/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 8c951903a..70caf5dae 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 fb0ed045a..fe04b9169 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
+}