Skip to content

Commit

Permalink
add fuzz against old
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-o-how committed Jan 15, 2025
1 parent e335adc commit 182b8e5
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 5 deletions.
7 changes: 5 additions & 2 deletions fuzz/fuzz_targets/deserialize_br.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_main]
use clvmr::allocator::Allocator;
use clvmr::serde::node_from_bytes_backrefs;
use clvmr::serde::node_from_bytes_backrefs_old;
use clvmr::serde::node_to_bytes_backrefs;
use libfuzzer_sys::fuzz_target;

Expand All @@ -17,9 +18,11 @@ fuzz_target!(|data: &[u8]| {

let mut allocator = Allocator::new();
let program = node_from_bytes_backrefs(&mut allocator, &b1).unwrap();

let program_old = node_from_bytes_backrefs_old(&mut allocator, &b1).unwrap();
let b2 = node_to_bytes_backrefs(&allocator, program).unwrap();
if b1 != b2 {
let b3 = node_to_bytes_backrefs(&allocator, program_old).unwrap();
if b1 != b2 || b1 != b3 {
panic!("b1 and b2 do not match");
}

});
62 changes: 60 additions & 2 deletions src/serde/de_br.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::io::{Cursor, Read};
use super::parse_atom::{parse_atom, parse_path};
use crate::allocator::{Allocator, NodePtr, SExp};
use crate::reduction::EvalErr;
use crate::traverse_path::{first_non_zero, msb_mask};
use crate::traverse_path::{first_non_zero, msb_mask, traverse_path};

const BACK_REFERENCE: u8 = 0xfe;
const CONS_BOX_MARKER: u8 = 0xff;
Expand Down Expand Up @@ -58,11 +58,65 @@ pub fn node_from_stream_backrefs(
Ok(values.pop().expect("Top of the stack"))
}

fn node_from_stream_backrefs_old(
allocator: &mut Allocator,
f: &mut Cursor<&[u8]>,
mut backref_callback: impl FnMut(NodePtr),
) -> io::Result<NodePtr> {
let mut values = allocator.nil();
let mut ops = vec![ParseOp::SExp];

let mut b = [0; 1];
while let Some(op) = ops.pop() {
match op {
ParseOp::SExp => {
f.read_exact(&mut b)?;
if b[0] == CONS_BOX_MARKER {
ops.push(ParseOp::Cons);
ops.push(ParseOp::SExp);
ops.push(ParseOp::SExp);
} else if b[0] == BACK_REFERENCE {
let path = parse_path(f)?;
let reduction = traverse_path(allocator, path, values)?;
let back_reference = reduction.1;
backref_callback(back_reference);
values = allocator.new_pair(back_reference, values)?;
} else {
let new_atom = parse_atom(allocator, b[0], f)?;
values = allocator.new_pair(new_atom, values)?;
}
}
ParseOp::Cons => {
// cons
// pop left and right values off of the "values" stack, then
// push the new pair onto it
let SExp::Pair(right, rest) = allocator.sexp(values) else {
panic!("internal error");
};
let SExp::Pair(left, rest) = allocator.sexp(rest) else {
panic!("internal error");
};
let new_root = allocator.new_pair(left, right)?;
values = allocator.new_pair(new_root, rest)?;
}
}
}
match allocator.sexp(values) {
SExp::Pair(v1, _v2) => Ok(v1),
_ => panic!("unexpected atom"),
}
}

pub fn node_from_bytes_backrefs(allocator: &mut Allocator, b: &[u8]) -> io::Result<NodePtr> {
let mut buffer = Cursor::new(b);
node_from_stream_backrefs(allocator, &mut buffer, |_node| {})
}

pub fn node_from_bytes_backrefs_old(allocator: &mut Allocator, b: &[u8]) -> io::Result<NodePtr> {
let mut buffer = Cursor::new(b);
node_from_stream_backrefs_old(allocator, &mut buffer, |_node| {})
}

pub fn node_from_bytes_backrefs_record(
allocator: &mut Allocator,
b: &[u8],
Expand Down Expand Up @@ -196,11 +250,15 @@ mod tests {
let buf = Vec::from_hex(serialization_as_hex).unwrap();
let mut allocator = Allocator::new();
let node = node_from_bytes_backrefs(&mut allocator, &buf).unwrap();
let mut oc = ObjectCache::new(&allocator, treehash);
let old_node = node_from_bytes_backrefs_old(&mut allocator, &buf).unwrap();
let mut oc = ObjectCache::new(&mut allocator, treehash);
let calculated_hash = oc.get_or_calculate(&node).unwrap();
let ch: &[u8] = calculated_hash;
let expected_hash: Vec<u8> = Vec::from_hex(expected_hash_as_hex).unwrap();
assert_eq!(expected_hash, ch);
let calculated_hash = oc.get_or_calculate(&old_node).unwrap();
let ch: &[u8] = calculated_hash;
assert_eq!(expected_hash, ch);
}

#[rstest]
Expand Down
2 changes: 1 addition & 1 deletion src/serde/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub mod write_atom;
mod test;

pub use de::node_from_bytes;
pub use de_br::{node_from_bytes_backrefs, node_from_bytes_backrefs_record};
pub use de_br::{node_from_bytes_backrefs, node_from_bytes_backrefs_record, node_from_bytes_backrefs_old};
pub use de_tree::{parse_triples, ParsedTriple};
pub use ser::{node_to_bytes, node_to_bytes_limit};
pub use ser_br::{node_to_bytes_backrefs, node_to_bytes_backrefs_limit};
Expand Down

0 comments on commit 182b8e5

Please sign in to comment.