santiagomed opened a new pull request, #3414:
URL: https://github.com/apache/thrift/pull/3414

   ## Problem
   
   When a struct contains a union-typed field and the wire data has a union 
variant (field ID) not present in the local IDL, the generated Rust code fails 
to deserialize the **entire struct** — not just the unknown union field.
   
   The root cause: the union`s `read_from_in_protocol` correctly returns 
`Err("received empty union")` for unknown variants (fixed in THRIFT-5926 / PR 
#3336). But the parent struct`s generated deserializer propagates this error 
via `?`, causing the whole struct to fail.
   
   This breaks Thrift`s forward-compatibility guarantee. When a server adds a 
new union variant, all clients running an older IDL version fail to parse any 
message containing that variant — even though the client doesn`t need to 
understand the new variant to process the rest of the struct.
   
   Java, Go, Python, and C++ Thrift all handle this gracefully: unknown union 
variants are silently skipped, and the struct field is left unset.
   
   ## Fix
   
   In `render_struct_sync_read`, detect struct fields whose type is a union. 
For those fields, wrap the `read_from_in_protocol` call in a `match` that 
catches the `"received empty union"` error and treats it as `None` (field 
absent):
   
   ```rust
   // Before (all fields):
   let val = FooUnion::read_from_in_protocol(i_prot)?;
   f_N = Some(val);
   
   // After (union fields only):
   match FooUnion::read_from_in_protocol(i_prot) {
       Ok(val) => { f_N = Some(val); },
       Err(thrift::Error::Protocol(ref e))
           if e.message.contains("received empty union") => {
           // forward compatibility: unknown union variant skipped
       },
       Err(e) => return Err(e),
   }
   ```
   
   Non-union fields are unchanged. The union`s own `TSerializable` impl is 
unchanged — it still returns `Err` for unknown variants, preserving the 
contract for callers that read unions directly.
   
   ## Impact
   
   - Fixes forward compatibility for all Rust Thrift users with evolving union 
schemas
   - No changes to the `TSerializable` trait or the thrift runtime library
   - No changes to the union`s own serialization/deserialization
   - Struct fields with union types that receive unknown variants get `None` 
instead of causing parse failure
   - All other errors (malformed data, I/O, multiple union fields) still 
propagate normally


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to