In the wincode SchemaWrite/SchemaRead impls for TrailingVec (collections/src/vec.rs:136-187) and the prefixed_vec_type! macro that builds U8/U16/U32/U64PrefixedVec (collections/src/vec.rs:259-328), elements are written as a raw byte copy (write_slice_t, sized by size_of::(), at vec.rs:162 and vec.rs:291) but read back via the schema (T::get, at vec.rs:179 and vec.rs:317), which causes the write and read to disagree on element size for any non-POD T, drifting the parse boundary so the field after the vector decodes to the wrong value. Very low likelihood this would ever hit, but worth covering the edge case.
Root cause: the impls only bound T: SchemaWrite with no plain-old-data restriction (vec.rs:139, vec.rs:262), so a mismatched element type compiles with no warning.
Impact: low / correctness, not security. Given that the code is relatively new, probably worth implementing a quick fix
Fix: at both sites, either bound the impls to POD elements, or write each element via SchemaWrite::write so the writer matches the reader. Cheap and non-breaking (no consumers, no wire-format change for POD types).
CC @febo
In the wincode SchemaWrite/SchemaRead impls for TrailingVec (collections/src/vec.rs:136-187) and the prefixed_vec_type! macro that builds U8/U16/U32/U64PrefixedVec (collections/src/vec.rs:259-328), elements are written as a raw byte copy (write_slice_t, sized by size_of::(), at vec.rs:162 and vec.rs:291) but read back via the schema (T::get, at vec.rs:179 and vec.rs:317), which causes the write and read to disagree on element size for any non-POD T, drifting the parse boundary so the field after the vector decodes to the wrong value. Very low likelihood this would ever hit, but worth covering the edge case.
Root cause: the impls only bound T: SchemaWrite with no plain-old-data restriction (vec.rs:139, vec.rs:262), so a mismatched element type compiles with no warning.
Impact: low / correctness, not security. Given that the code is relatively new, probably worth implementing a quick fix
Fix: at both sites, either bound the impls to POD elements, or write each element via SchemaWrite::write so the writer matches the reader. Cheap and non-breaking (no consumers, no wire-format change for POD types).
CC @febo