Skip to content

bufio: Reader.UnreadByte after Discard silently corrupts input #48446

@bcmills

Description

@bcmills

What did you do?

On a bufio.Reader, invoke ReadByte, then Discard one or more bytes, then UnreadByte (https://play.golang.org/p/RTitxKuiikQ):

package main

import (
	"bufio"
	"strings"
	"testing"
)

func TestBytesBufferUnreadByte(t *testing.T) {
	check := func(err error) {
		if err != nil {
			t.Helper()
			t.Fatal(err)
		}
	}

	const in = "abc\n"
	t.Logf("reading %q", in)

	b := bufio.NewReader(strings.NewReader(in))

	c, err := b.ReadByte()
	check(err)
	t.Logf("read byte %q", c)

	n, err := b.Discard(1)
	check(err)
	t.Logf("discarded %v byte(s)", n)

	err = b.UnreadByte()
	t.Logf("UnreadByte: %v", err)
	var want string
	if err == nil {
		want = in[1:]
	} else {
		want = in[2:]
	}

	s, err := b.ReadString('\n')
	check(err)
	if s != want {
		t.Fatalf("buffer corrupted: read %q, expected %q", s, want)
	}
}

What did you expect to see?

UnreadByte after Discard either restores the last discarded byte, or returns a non-nil error and does not modify the buffered data.

What did you see instead?

UnreadByte overwrites the last discarded byte with the last byte returned from the last Read* call.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions