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

proposal: io: add ZeroReader io.Reader #57317

Closed
tmthrgd opened this issue Dec 15, 2022 · 8 comments
Closed

proposal: io: add ZeroReader io.Reader #57317

tmthrgd opened this issue Dec 15, 2022 · 8 comments

Comments

@tmthrgd
Copy link
Contributor

tmthrgd commented Dec 15, 2022

Needing to read a stream of zero-bytes is an ocassional use-case of an io.Reader. io.ZeroReader would be the /dev/zero counterpoint to /dev/null and io.Discard.

One particular use-case is with cipher.StreamReader to create a CSPRNG (this is the crypto/ecdsa use below).

I've proposed it be called io.ZeroReader, but it could also be called io.Zero or similar.


Proposed API:

package io

// ZeroReader is a Reader that reads an endless stream of zero-bytes.
var ZeroReader Reader = zeroReader{}

type zeroReader struct{} 
 
func (zeroReader) Read(p []byte) (int, error) { 
	for i := range p { 
		p[i] = 0 
	} 
	return len(p), nil 
}

There are two uses of this I can find in the standard library:

type zeroReader struct{}
func (zeroReader) Read(b []byte) (int, error) {
for i := range b {
b[i] = 0
}
return len(b), nil
}

type zr struct{}
var zeroReader = zr{}
// Read replaces the contents of dst with zeros. It is safe for concurrent use.
func (zr) Read(dst []byte) (n int, err error) {
for i := range dst {
dst[i] = 0
}
return len(dst), nil
}

...and five more in test code: here and here.

Admittedly the archive/tar use could be written differently (it seems to be just zeroing a slice), but the crypto/ecdsa use does require it.

There are also two examples in the standard library of io.ReaderAt zeroing:

// zeroReaderAt is ReaderAt that reads 0s.
type zeroReaderAt struct{}
// ReadAt writes len(p) 0s into p.
func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
for i := range p {
p[i] = 0
}
return len(p), nil
}

go/src/debug/pe/file.go

Lines 185 to 194 in ea14d1b

// zeroReaderAt is ReaderAt that reads 0s.
type zeroReaderAt struct{}
// ReadAt writes len(p) 0s into p.
func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
for i := range p {
p[i] = 0
}
return len(p), nil
}

@gopherbot gopherbot added this to the Proposal milestone Dec 15, 2022
@DeedleFake
Copy link

If you leave it as zeroing only this could make use of #56351, but you could also make it a bit more flexible by making it something like type RepeatReader struct { Value byte } or something and then make it fill the slice with Value instead of just 0.

@seankhliao

This comment was marked as resolved.

@seankhliao seankhliao marked this as a duplicate of #48897 Dec 15, 2022
@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Dec 15, 2022
@tmthrgd

This comment was marked as resolved.

@seankhliao seankhliao reopened this Dec 15, 2022
@rsc
Copy link
Contributor

rsc commented Dec 21, 2022

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc
Copy link
Contributor

rsc commented Jan 4, 2023

There is a question of what type to give this thing. It is both a Reader and a ReaderAt, and we don't have an interface for that type. We would probably need to do:

var Zero ZeroReader

func (ZeroReader) Read
func (ZeroReader) ReadAt

There is also potential confusion with it being a reader that has no (zero) bytes in length, not a reader that has an infinite number of zero bytes. "A reader that returns 0 bytes" can be read either way.

There is also the question of whether this arises enough to be worthwhile. The uses in the standard library are pretty fringe. I might also worry about uses in crypto and then having to preserve some properties of the implementation that we might or might not remember to preserve.

Are the use cases really here?

@rsc
Copy link
Contributor

rsc commented Jan 11, 2023

Note that the new clear builtin will shorten the implementation of these, making it even easier to maintain them outside the standard library.

@rsc
Copy link
Contributor

rsc commented Jan 11, 2023

Based on the discussion above, this proposal seems like a likely decline.
— rsc for the proposal review group

@rsc
Copy link
Contributor

rsc commented Jan 18, 2023

No change in consensus, so declined.
— rsc for the proposal review group

@rsc rsc closed this as completed Jan 18, 2023
@golang golang locked and limited conversation to collaborators Jan 18, 2024
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

5 participants