-
Notifications
You must be signed in to change notification settings - Fork 18k
bufio: return error from UnreadByte/UnreadRune after Peek #18556
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
Comments
I suspect the code is working as intended. Do people agree that the documentation for UnreadRune() could be clearer? It wasn't clear to me that Peek() is considered a "read operation" in this context. Or perhaps peek isn't considered a "read operation" and the documentation should say "read or peek operation" or similar? |
This is working as intended.
It may make sense to slightly clarify the documentation about what |
Another observation is that typically Peek doesn't stop UnreadRune working, it only does so under certain conditions (such as those in my attached test) So even adding something saying that |
It seems like a bug and/or incorrect documentation to me. If the range of the for loop is changed to 15, the test passes. That's because there's still enough data in the buffer to satisfy the peek and internally Either way something is wrong: If |
This is not restricted to ReadRune/UnreadRune - ReadByte/UnreadByte have the same error |
I suspect this is the case. So this is not just a doc issue, because we also need to change |
UnreadRune and UnreadByte were defined before Peek existed. I agree that if Peek has happened since the last rune or byte read, these should return an error. |
If anyone wants to send a CL, please do (for Go 1.10). |
I will have a go at this in the next day or two. |
CL https://golang.org/cl/46850 mentions this issue. |
I think some kind of documentation change is still needed. The commit message says:
What exactly in the documentation says that this behavior is allowed? The documentation for Unread says
and nothing in Peek says anything about Unread*. IMO the Unread* operations should document more specifically which calls can precede them. For another example, the documentation doesn't say whether I can Discard() and then Unread() ... though I can't imagine why anyone would do that. |
Thanks for pointing out that this change went in @heschik. I rolled it back. This was supposed to be for Go 1.10. |
Do we still want to make this change? It's after the freeze... or are we going to push to Go1.11? |
@dsnet, let's do this for Go 1.10. You want to re-apply it and include some docs? |
Too late now, push to Go 1.11 |
How about for 1.12? Not having this has made real bugs hard to find twice for me, so I still think it's worth going. |
@mjgarton Want to send a patch? Thanks. |
Since Reader.Peek potentially reads from the underlying io.Reader, discarding previous buffers, UnreadRune and UnreadByte cannot necessarily work. Change Peek to invalidate the unread buffers in all cases (as allowed according to the documentation) and thus prevent hiding bugs in the caller. (This change was previoiusly merged and then reverted due concern about being too close to a release) Fixes golang#18556 Change-Id: Iebcdaa8f73de610997350121a4d115fe378fa387
Since Reader.Peek potentially reads from the underlying io.Reader, discarding previous buffers, UnreadRune and UnreadByte cannot necessarily work. Change Peek to invalidate the unread buffers in all cases (as allowed according to the documentation) and thus prevent hiding bugs in the caller. (This change was previoiusly merged and then reverted due concern about being too close to a release) Fixes golang#18556
Change https://golang.org/cl/149297 mentions this issue: |
Here is a concrete call site that will silently break as a result of this change, because it does not check the error from (Note that It is not obvious to me whether that call site is already silently broken in some cases. |
The call site in In particular, if we execute |
For that matter, it's not obvious that we need to invalidate Preserving |
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?go version go1.7.3 linux/amd64
What operating system and processor architecture are you using (
go env
)?GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/mgarton/gopath"
GORACE=""
GOROOT="/home/mgarton/go"
GOTOOLDIR="/home/mgarton/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build323320002=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
What did you do?
I ran this:
What did you expect to see?
Either the test should pass, or the documentation for bufio.Reader.UnreadRune should mention that Peek can prevent UnreadRune from working.
What did you see instead?
The test fails.
If someone tells me whether this is a code bug or a documentation issue, I'm happy to attempt a CL
The text was updated successfully, but these errors were encountered: