-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[protoreflect] Message.WhichOneof for generated message type panics when given synthetic oneof #1659
Comments
I also just encountered this panic in v1.36.0 through a different route. Attempting to encode a message using I am aware |
version |
Current behavior is documented to be correct:
That is: calling |
Regardless of the documentation correctness, this seems to be a breaking change - I've experienced many services breaking due to this and it breaks in a vey bad way since it's something that is frequently not tested - production servers panicking. Maybe it has the extremes for a security vulnerability? |
I believe this is not the Security exception to go1compat, but Bugs according to the go1compat rules. This behavior never should have worked, because optional fields were never actually oneofs. Therefore, that this worked before was out of specification. |
I am quite unknowledgeable on the rules, it still feel very that is a drastic behavioral change, if this wasn't supposed to work before I would have expected compilation issues, right now we have a situation where attackers can crash a server by just tuning some query parameters which is a great recipe for denial of service attacks. Maybe it shouldn't have been there from the beginning but it is already out and there are people running servers out there leveraging this behavior. If we want to pursue this correction my take is that it should come with a more diligent governance starting from the compiler, going through (if possible) deprecation warnings and only at the very end panicking. |
In my case I am experiencing that when using in conjunction with grpc-gateway: rpc Echo(MessageRequest) returns (MessageResponse) {
option (google.api.http) = {
get: "/v1/example/resource"
};
}
message MessageRequest {
int32 query_filter = 1;
optional string optional_query_filter = 2;
} |
Possibly relevant observation: |
Relevant |
If this changed, we should probably restore the original behavior regardless of what the documentation says. |
Sorry for the breakage, folks. Maybe I misunderstood something in how this behavior is meant to work. I’ll look into it on Monday when I’m in the office. |
This reverts change https://go.dev/cl/632735, in which I misunderstood what the Protobuf documentation wanted to convey: The quoted docs in CL 632735 refer to reflection for proto3 optional fields, not to reflection for proto3 synthetic oneofs. Synthetic oneofs should remain visible through reflection. For the Open API, this change restores the old behavior. For the Opaque API, another fix is needed and will be sent in a separate, follow-up CL (follow golang/protobuf#1659). For golang/protobuf#1659 Thanks to Joshua Humphries for the report and reproducer! Change-Id: I3a924eed6d2425581adc65651395a68fc1576f4d Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/638495 Reviewed-by: Chressie Himpel <chressie@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This is the equivalent of CL 638495, but for the Opaque API. While the behavior is the same for non-synthetic oneofs between the Open Struct API and Opaque API, the behavior for synthetic oneofs is not the same: Because the Opaque API uses a bitfield to store presence, we need to use the Opaque presence check in WhichOneof(). This CL extends the testproto generator to use the protoc command-line flag for the test3 testproto (which specifies syntax = "proto3";), as the in-file api_level is only available in .proto files using editions (but editions does not use synthetic oneofs for optional fields, only proto3 does). For golang/protobuf#1659 Change-Id: I0a1fd6e5fc6f96eeab043f966728ce2a14dbd446 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/638515 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Chressie Himpel <chressie@google.com>
OK, I have had a chance to look into this issue some more. As I suspected, I had not correctly understood the situation when I made this change. I’m sorry for the extra work this caused everyone. By now, we have made two changes:
We will release v1.36.2 in January and will leave this issue open until then for visibility. Happy holidays everyone! |
What version of protobuf and what language are you using?
v1.36.0
What did you do?
Here's a reproducer test case.
protocolbuffers/protobuf-go@master...jhump:protobuf-go:jh/panic-repro
The panic happens in the call to
msg.WhichOneof
(line 20).What did you expect to see?
In prior versions, at least as recently as 1.34.0, this worked as expected. It would return nil if the underlying proto3 optional field was present and otherwise it would return its field descriptor.
What did you see instead?
Anything else we should know about your project / environment?
Occurs on both OS X and Linux.
The following patch fixes the issue:
However, the file in question (
internal/impl/message_reflect_gen.go
) is generated. So a real fix will have to be made in the code generator or perhaps to reverse whatever change caused synthetic oneofs to no longer appear inmi.oneofs
.The text was updated successfully, but these errors were encountered: