@@ -512,10 +512,7 @@ impl<T: Timestamp + Codec64> RustType<ProtoStateDiff> for StateDiff<T> {
512512 proto. latest_rollup_key . into_rust ( ) ?,
513513 ) ;
514514 if let Some ( field_diffs) = proto. field_diffs {
515- // `field_diffs` is decoded from an untrusted blob, so validate it and
516- // return a decode error on a malformed/crafted diff rather than a
517- // `debug_assert` (which panics under debug assertions / fuzzing and
518- // is compiled out in release, where the bad data flowed through).
515+ // `field_diffs` is decoded from an untrusted blob, so validate it.
519516 field_diffs
520517 . validate ( )
521518 . map_err ( TryFromProtoError :: InvalidPersistState ) ?;
@@ -1097,11 +1094,9 @@ impl<T: Timestamp + Lattice + Codec64> RustType<ProtoRollup> for Rollup<T> {
10971094
10981095 let diffs: Option < InlinedDiffs > = x. diffs . map ( |diffs| diffs. into_rust ( ) ) . transpose ( ) ?;
10991096 if let Some ( diffs) = & diffs {
1100- // The diff bounds are validated against the latest rollup, which
1101- // `State::latest_rollup` `.expect()`s to exist. A proto that carries
1102- // diffs but no rollups is malformed, so reject it here rather than
1103- // panicking. A rollup-less state with no diffs, such as a freshly
1104- // initialized state, is fine and must still decode.
1097+ // `latest_rollup` below `.expect()`s a rollup to exist, so a proto
1098+ // with diffs but no rollups would panic. (A rollup-less state
1099+ // without diffs skips this block and decodes fine.)
11051100 if state. collections . rollups . is_empty ( ) {
11061101 return Err ( TryFromProtoError :: InvalidPersistState (
11071102 "rollup state has diffs but no rollups" . into ( ) ,
@@ -1673,12 +1668,9 @@ impl<T: Timestamp + Codec64> RustType<ProtoHollowBatchPart> for BatchPart<T> {
16731668 } ) )
16741669 }
16751670 Some ( proto_hollow_batch_part:: Kind :: Inline ( x) ) => {
1676- // An inline part carries its data in `kind`; the hollow-only
1677- // fields must be unset. These are decoded from an untrusted
1678- // blob, so validate and return a decode error rather than
1679- // asserting (which panicked, even in release, on a
1680- // malformed/crafted part). Found by the rollup_proto_roundtrip
1681- // cargo-fuzz target.
1671+ // An inline part keeps its data in `kind`; the hollow-only
1672+ // fields must be unset. Decoded from an untrusted blob, so
1673+ // validate rather than assert.
16821674 if proto. encoded_size_bytes != 0
16831675 || !proto. key_lower . is_empty ( )
16841676 || proto. key_stats . is_some ( )
@@ -1924,9 +1916,8 @@ impl<T: Timestamp + Codec64> RustType<ProtoU64Description> for Description<T> {
19241916
19251917 fn from_proto ( proto : ProtoU64Description ) -> Result < Self , TryFromProtoError > {
19261918 let lower: Antichain < T > = proto. lower . into_rust_if_some ( "lower" ) ?;
1927- // `Description::new` asserts a non-empty lower frontier. `lower` is
1928- // decoded from an untrusted blob, so validate it here and return a
1929- // decode error rather than panicking on a crafted/corrupted batch.
1919+ // `Description::new` asserts a non-empty lower frontier; `lower` comes
1920+ // from an untrusted blob, so validate it here instead of panicking.
19301921 if lower. elements ( ) . is_empty ( ) {
19311922 return Err ( TryFromProtoError :: InvalidPersistState (
19321923 "ProtoU64Description has an empty lower frontier" . into ( ) ,
@@ -1985,9 +1976,8 @@ mod tests {
19851976 #[ mz_ore:: test]
19861977 fn rollup_inline_batch_part_with_hollow_fields_is_error ( ) {
19871978 // An inline `ProtoHollowBatchPart` carrying hollow-only fields (here a
1988- // non-zero encoded_size_bytes) must decode to an error, not panic. It
1989- // used to `assert!`, which fired even in release on a crafted/corrupted
1990- // blob. Regression for the rollup_proto_roundtrip cargo-fuzz finding.
1979+ // non-zero encoded_size_bytes) must decode to an error, not panic.
1980+ // Regression for a rollup_proto_roundtrip fuzz finding.
19911981 use mz_proto:: ProtoType ;
19921982 use prost:: Message ;
19931983 let bytes: & [ u8 ] = & [
@@ -2003,9 +1993,8 @@ mod tests {
20031993 #[ mz_ore:: test]
20041994 fn rollup_batch_with_empty_lower_frontier_is_error ( ) {
20051995 // A `ProtoU64Description` with an empty lower frontier must decode to an
2006- // error: `Description::new` asserts a non-empty lower, so a crafted batch
2007- // used to panic. Regression for the rollup_proto_roundtrip cargo-fuzz
2008- // finding.
1996+ // error: `Description::new` asserts a non-empty lower. Regression for a
1997+ // rollup_proto_roundtrip fuzz finding.
20091998 use mz_proto:: ProtoType ;
20101999 use prost:: Message ;
20112000 let bytes: & [ u8 ] = & [
@@ -2346,10 +2335,8 @@ mod tests {
23462335 }
23472336
23482337 /// A batch whose since is past the trace's since reconstructs without
2349- /// tripping any spine assert but violates `Trace::validate`, which used
2350- /// to run only under `debug_assert` (a panic in cargo-fuzz builds, silent
2351- /// acceptance of corrupted state in release builds). It must be a decode
2352- /// error.
2338+ /// tripping any spine assert but violates `Trace::validate`, which used to
2339+ /// run only under `debug_assert`. It must be a decode error.
23532340 #[ mz_ore:: test]
23542341 fn rollup_proto_with_batch_since_past_trace_since_is_rejected ( ) {
23552342 let proto = rollup_proto_with_trace ( |trace| {
@@ -2360,8 +2347,8 @@ mod tests {
23602347 }
23612348
23622349 /// An absurd batch len overflows the spine's maintenance arithmetic
2363- /// (`len.next_power_of_two()`, summing lens of merged batches), which
2364- /// panics in builds with overflow checks. It must be a decode error.
2350+ /// (`len.next_power_of_two()`, summing merged batch lens). It must be a
2351+ /// decode error.
23652352 #[ mz_ore:: test]
23662353 fn rollup_proto_with_absurd_batch_len_is_rejected ( ) {
23672354 let proto = rollup_proto_with_trace ( |trace| {
@@ -2375,9 +2362,8 @@ mod tests {
23752362 assert ! ( err. contains( "maximum trace size" ) , "{err}" ) ;
23762363 }
23772364
2378- /// An absurd spine batch level previously overflowed `level + 1` (a panic
2379- /// in builds with overflow checks) and sized a `vec![]` allocation (an
2380- /// abort). It must be a decode error.
2365+ /// An absurd spine batch level previously overflowed `level + 1` and sized
2366+ /// a giant `vec![]` allocation. It must be a decode error.
23812367 #[ mz_ore:: test]
23822368 fn rollup_proto_with_absurd_spine_level_is_rejected ( ) {
23832369 let proto = rollup_proto_with_trace ( |trace| {
0 commit comments