-
Notifications
You must be signed in to change notification settings - Fork 25
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
Fix read bug in readByteBuf #60
Fix read bug in readByteBuf #60
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Note: there is a tiny problem here. Ideally we would return EOF if we read no bytes at all. But that's probably not worth it. |
Okay. Agreed. I’ll make that change later today. |
Updated and added a comment here https://github.com/whyrusleeping/cbor-gen/pull/60/files#diff-189b40dd496fee4378c7839f550f27e38db377a64fbe0881ce48651f0ac809faR64-R68 That explains the general logic of when things return EOF vs. ErrUnexpectedEOF. |
074f2b2
to
1b35ba1
Compare
I think this is correct, but then what's the point of
|
Continuing the thought above, I think most of the old code is correct. EOF happens when we read no bytes and ErrUnexpectedEOF when we read some but not all and ran into EOF. So I'm going to discard most of the commits and fix only the readByte and readByteBuf, and check that discard follows the same semantics. |
Because we were using
|
1b35ba1
to
5608d45
Compare
yep! I think we're on the same page. My point was that with that change ReadExact becomes ReadFull, or in other words the implementation of ReadExact becomes: func ReadExact(r io.Reader, buf []byte) error {
_, err := io.ReadFull(r, buf)
return err
} So then a lot of the changes in #44 aren't needed. |
Updated this PR and the description. I took out most of the changes from #44 because they aren't needed since io.ReadFull already does this. I fixed the bug in readByteBuf, and I made For general reference, the comment on io.EOF also summarizes this distinction pretty well:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strictly speaking, this code is correct. But it doesn't fix the original bug. We need to ensure that UnmarshalCBOR
returns:
io.EOF
if it reads nothing.io.UnexpectedEOF
if it reads some data but hits an EOF before it finishes the object.
As far as I can tell, the current code can still return an EOF
if, e.g., stop reading a CBOR object on some field boundary.
Yeah I think that's true. This does fix the other bug in @Stebalien / @whyrusleeping could either of you merge this? I don't have that ability |
Done. |
The dependency to cbor-gen includes a bug fix on how `readByteBuf` handled errors. See: - whyrusleeping/cbor-gen#60
readByteBuf was incorrectly returning the error (EOF) before returning the first byte read. It is a valid for an io.Reader to return both n == 1 and err == EOF (see https://pkg.go.dev/io#Reader). But readByteBuf dropped the read byte and instead returned EOF.
This uses io.ReadFull to handle this logic, where io.ReadFull follows these semantics:
This also makes sure that the
discard
helper also follows those semantics. Returning EOF if no bytes were discarded and ErrUnexpectedEOF if only some of the bytes were discarded.Note this started as a continuation of #44, but we realized along the way that most of this code was correct by the semantics above.
This change fixes two things: