Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bytes: bytes.Reader violates the io.Reader and io.EOF main principle #59253

Closed
vault-thirteen opened this issue Mar 26, 2023 · 3 comments
Closed

Comments

@vault-thirteen
Copy link

What version of Go are you using (go version)?

go version go1.20.2 windows/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

O.S. is Microsoft Windows 10.
CPU uses Intel x86-64 (a.k.a. AMD64) architecture.

What did you do?

I tried to use a byte.Reader to read bytes.
The program's source code is following.

package main

import (
	"bytes"
	"fmt"
)

func main() {
	br := bytes.NewReader([]byte{1})
	expectedTwoBytes := make([]byte, 2)
	n, err := br.Read(expectedTwoBytes)
	report := fmt.Sprintf("n=%v, err=%v, expectedTwoBytes=%v.", n, err, expectedTwoBytes)
	fmt.Println(report)
}

What did you expect to see?

I expected to see the result according to what the built-in io package states.
It states following:

// EOF is the error returned by Read when no more input is available.
// (Read must return EOF itself, not an error wrapping EOF,
// because callers will test for EOF using ==.)
// Functions should return EOF only to signal a graceful end of input.
// If the EOF occurs unexpectedly in a structured data stream,
// the appropriate error is either ErrUnexpectedEOF or some other error
// giving more detail.
var EOF = errors.New("EOF")

The key thing here is the first line:

EOF is the error returned by Read when no more input is available.

The code provided above tries to read two bytes from a bytes.Reader having only one byte available.
The bytes.Reader does not return the io.EOF error when no more input is available.
This makes me think that bytes.Reader is violating the main principle of the io.Reader and io.EOF.

What did you see instead?

n=1, err=<nil>, expectedTwoBytes=[1 0].
@vault-thirteen vault-thirteen changed the title affected/package: bytes bytes package violates the io.Reader and io.EOF main principle Mar 26, 2023
@vault-thirteen vault-thirteen changed the title bytes package violates the io.Reader and io.EOF main principle bytes: bytes.Reader violates the io.Reader and io.EOF main principle Mar 26, 2023
@seankhliao
Copy link
Member

from io.Reader:

It may return the (non-nil) error from the same call or return the error (and n == 0) from a subsequent call. An instance of this general case is that a Reader returning a non-zero number of bytes at the end of the input stream may return either err == EOF or err == nil. The next Read should return 0, EOF.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Mar 26, 2023
@vault-thirteen
Copy link
Author

Hello, seankhliao.

Thank you for your quote of the documenation at https://pkg.go.dev/io#Reader.

An instance of this general case is that a Reader returning a non-zero number of bytes at the end of the input stream may return either err == EOF or err == nil. The next Read should return 0, EOF.

I must say that in such case this text taken from the documentation is contrary to the main principle stated in the comments inside the source code of the io.EOF.

The documentation in the comments of the source code states that an io.EOF error is returned.

EOF is the error returned by Read when no more input is available.

@vault-thirteen
Copy link
Author

I have opened another issue about the controversy in the documentation:
#59254

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants