1
1
#![ no_main]
2
2
mod fuzzing_utils;
3
3
mod make_tree;
4
+ mod pick_node;
5
+ mod serialized_len;
4
6
5
- use clvmr:: serde:: { node_to_bytes , serialized_length, treehash, ObjectCache } ;
6
- use clvmr:: { Allocator , NodePtr , SExp } ;
7
+ use clvmr:: serde:: { serialized_length, treehash, ObjectCache } ;
8
+ use clvmr:: Allocator ;
7
9
use fuzzing_utils:: tree_hash;
8
10
use libfuzzer_sys:: fuzz_target;
9
- use std:: collections:: hash_map:: Entry ;
10
- use std:: collections:: HashMap ;
11
- use std:: collections:: HashSet ;
12
-
13
- enum Op {
14
- Cons ( NodePtr ) ,
15
- Traverse ( NodePtr ) ,
16
- }
17
-
18
- fn compute_serialized_len ( a : & Allocator , n : NodePtr ) -> u64 {
19
- let mut stack: Vec < u64 > = vec ! [ ] ;
20
- let mut op_stack = vec ! [ Op :: Traverse ( n) ] ;
21
- let mut cache = HashMap :: < NodePtr , u64 > :: new ( ) ;
22
-
23
- while let Some ( op) = op_stack. pop ( ) {
24
- match op {
25
- Op :: Cons ( node) => {
26
- let right = stack. pop ( ) . expect ( "internal error, empty stack" ) ;
27
- let left = stack. pop ( ) . expect ( "internal error, empty stack" ) ;
28
- match cache. entry ( node) {
29
- Entry :: Occupied ( e) => stack. push ( * e. get ( ) ) ,
30
- Entry :: Vacant ( e) => {
31
- e. insert ( 1 + left + right) ;
32
- stack. push ( 1 + left + right) ;
33
- }
34
- }
35
- }
36
- Op :: Traverse ( node) => match cache. entry ( node) {
37
- Entry :: Occupied ( e) => stack. push ( * e. get ( ) ) ,
38
- Entry :: Vacant ( e) => match a. sexp ( node) {
39
- SExp :: Pair ( left, right) => {
40
- op_stack. push ( Op :: Cons ( node) ) ;
41
- op_stack. push ( Op :: Traverse ( left) ) ;
42
- op_stack. push ( Op :: Traverse ( right) ) ;
43
- }
44
- SExp :: Atom => {
45
- let ser_len = node_to_bytes ( a, node)
46
- . expect ( "internal error, failed to serialize" )
47
- . len ( ) as u64 ;
48
- e. insert ( ser_len) ;
49
- stack. push ( ser_len) ;
50
- }
51
- } ,
52
- } ,
53
- }
54
- }
55
- assert_eq ! ( stack. len( ) , 1 ) ;
56
- * stack. last ( ) . expect ( "internal error, empty stack" )
57
- }
58
-
59
- fn pick_node ( a : & Allocator , root : NodePtr , mut node_idx : i32 ) -> NodePtr {
60
- let mut stack = vec ! [ root] ;
61
- let mut seen_node = HashSet :: < NodePtr > :: new ( ) ;
62
-
63
- while let Some ( node) = stack. pop ( ) {
64
- if node_idx == 0 {
65
- return node;
66
- }
67
- if !seen_node. insert ( node) {
68
- continue ;
69
- }
70
- node_idx -= 1 ;
71
- if let SExp :: Pair ( left, right) = a. sexp ( node) {
72
- stack. push ( left) ;
73
- stack. push ( right) ;
74
- }
75
- }
76
- NodePtr :: NIL
77
- }
11
+ use serialized_len:: compute_serialized_len;
78
12
79
13
fuzz_target ! ( |data: & [ u8 ] | {
80
14
let mut unstructured = arbitrary:: Unstructured :: new( data) ;
@@ -86,8 +20,7 @@ fuzz_target!(|data: &[u8]| {
86
20
let mut length_cache = ObjectCache :: new( serialized_length) ;
87
21
88
22
let node_idx = unstructured. int_in_range( 0 ..=node_count) . unwrap_or( 5 ) as i32 ;
89
-
90
- let node = pick_node( & allocator, tree, node_idx) ;
23
+ let node = pick_node:: pick_node( & allocator, tree, node_idx) ;
91
24
92
25
let expect_hash = tree_hash( & allocator, node) ;
93
26
let expect_len = compute_serialized_len( & allocator, node) ;
0 commit comments