//! Decrypted item plaintext: JSON parse, Item model parse, and the per-item replay checks and merge that //! run on every pulled record. Input: two plaintexts (held base, incoming) separated by a 0xFF byte. #![no_main] use kv_model::Item; use kv_sync::{merge::merge3, replay}; use libfuzzer_sys::fuzz_target; use serde_json::Value; use uuid::Uuid; fuzz_target!(|data: &[u8]| { let (a, b) = match data.iter().position(|&c| c == 0xff) { Some(i) => (&data[..i], &data[i + 1..]), None => (data, &data[..0]), }; let Ok(incoming) = serde_json::from_slice::(a) else { return }; let _ = serde_json::from_value::(incoming.clone()); let id = Uuid::from_u128(1); let held: Option = serde_json::from_slice(b).ok(); let base = match &held { Some(v) => replay::Base::Sealed(v), None => replay::Base::LegacyTombstone, }; for deleted in [false, true] { let _ = replay::check_pulled(base, id, deleted, Some(&incoming)); } // An identical record is never a replay. assert!(replay::check_successor(replay::Base::Sealed(&incoming), &incoming).is_ok()); let next = replay::next_version(Some(&incoming), base); assert!(next > replay::seq_of(&incoming) || replay::seq_of(&incoming) == u64::MAX); if let Some(h) = &held { let _ = merge3(None, h, &incoming); let _ = merge3(Some(h), &incoming, h); let _ = replay::same_content(h, &incoming); } });