You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The NextMessage function is not equipped to handle short reads, it just assumes that the entire payload can be read with one syscall, and what's worse, it has a subtle bug when it attempts to report this error case.
The issue can be demonstrated with the following strace extract:
The go code that produced this trace is very similar to the example code around here, it calls NextMessage in a loop, checks for errors, and then attempts to process the received packet in a switch, depending on the packet's Kind().
In this case it first reads a proper packet header, learns that the payload should be 320 bytes long and then attempts to read that many bytes. However, it only reads 103 bytes, and then it returns. The next call to NextMessage then interprets whatever audio sample that was in the buffer as the header of the next packet.
What makes this worse is a subtle bug in errors.Wrapf, as used in NextMessage:
if n != int(payloadLen) {
return nil, errors.Wrapf(err, "read wrong number of bytes (%d) for payload", n)
}
If err is nil, as in this case, the value returned by errors.Wrapf is also nil! This can be examined in the following playground link: https://go.dev/play/p/5zHdS1_Crkr
Proposed steps to fix:
handle short reads properly, by calling Read() in a loop until error or enough bytes were read
don't use errors.Wrapf when err is nil, or even better, don't use github.com/pkg/errors at all, it's considered deprecated nowadays
The text was updated successfully, but these errors were encountered:
The NextMessage function is not equipped to handle short reads, it just assumes that the entire payload can be read with one syscall, and what's worse, it has a subtle bug when it attempts to report this error case.
The issue can be demonstrated with the following strace extract:
The go code that produced this trace is very similar to the example code around here, it calls NextMessage in a loop, checks for errors, and then attempts to process the received packet in a switch, depending on the packet's Kind().
In this case it first reads a proper packet header, learns that the payload should be 320 bytes long and then attempts to read that many bytes. However, it only reads 103 bytes, and then it returns. The next call to NextMessage then interprets whatever audio sample that was in the buffer as the header of the next packet.
What makes this worse is a subtle bug in errors.Wrapf, as used in NextMessage:
If err is nil, as in this case, the value returned by errors.Wrapf is also nil! This can be examined in the following playground link: https://go.dev/play/p/5zHdS1_Crkr
Proposed steps to fix:
The text was updated successfully, but these errors were encountered: