-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
grpc: fix receiving empty messages when compression is enabled and maxReceiveMessageSize is maxInt64 #7753 #7918
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #7918 +/- ##
==========================================
+ Coverage 81.84% 82.12% +0.27%
==========================================
Files 377 378 +1
Lines 38120 38269 +149
==========================================
+ Hits 31201 31428 +227
+ Misses 5603 5542 -61
+ Partials 1316 1299 -17
|
rpc_util.go
Outdated
if err != nil { | ||
out.Free() | ||
return nil, 0, err | ||
} | ||
if err = checkReceiveMessageOverflow(int64(out.Len()), int64(maxReceiveMessageSize), dcReader); err != nil { | ||
return nil, out.Len() + 1, err |
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.
Adding 1 to out.Len()
can result in an overflow on 32 bit systems. The following part of the function seems strange to me:
Optionally, if data will be over maxReceiveMessageSize, just return the size
I suggest making the following change to avoid this:
- Declare a global error for indicating that the max receive size is exceeded:
var errMaxMessageSizeExceeded = errors.New("max message size exceeded")
- When the check here fails,
nil, 0, errMaxMessageSizeExceeded
. Update the godoc to mention the same. - In the caller, i.e. recvAndDecompress, instead of checking
if size > maxReceiveMessageSize
, checkif err == errMaxMessageSizeExceeded
. Also update the error message to not mention the actual size, because we didn't read the entire message anyways:grpc: received message after decompression larger than max %d
.
This ensures we're using the returned error to indicate the failure instead of relying on special values of the bytes read count.
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.
Please let the reviewer resolve comments.
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.
We should not attempt to add out.Len() + 1
, instead return errMaxMessageSizeExceeded
to signal the same.
rpc_util.go
Outdated
// If additional data is read, or an error other than `io.EOF` is encountered, the function | ||
// returns an error indicating that the message size has exceeded the permissible limit. | ||
func checkReceiveMessageOverflow(readBytes, maxReceiveMessageSize int64, dcReader io.Reader) error { | ||
if readBytes == maxReceiveMessageSize { |
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.
You can invert this check and returns early to reduce indentation.
if readBytes < maxReceiveMessageSize {
return nil
}
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.
I fixed all the comments.
rpc_util.go
Outdated
if err != nil { | ||
out.Free() | ||
return nil, 0, err | ||
} | ||
if err = checkReceiveMessageOverflow(int64(out.Len()), int64(maxReceiveMessageSize), dcReader); err != nil { | ||
return nil, out.Len() + 1, err |
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.
Please let the reviewer resolve comments.
rpc_util.go
Outdated
if err != nil { | ||
out.Free() | ||
return nil, 0, err | ||
} | ||
if err = checkReceiveMessageOverflow(int64(out.Len()), int64(maxReceiveMessageSize), dcReader); err != nil { | ||
return nil, out.Len() + 1, err |
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.
We should not attempt to add out.Len() + 1
, instead return errMaxMessageSizeExceeded
to signal the same.
Fixes #4552
RELEASE NOTES: