Skip to content

Commit ea5a906

Browse files
committed
Address reviewer comments
1 parent 65fb01c commit ea5a906

1 file changed

Lines changed: 19 additions & 33 deletions

File tree

src/persist-client/src/internal/encoding.rs

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)