forked from stellar/rs-soroban-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fuzz_rawval_cmp.rs
145 lines (123 loc) · 4.21 KB
/
fuzz_rawval_cmp.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#![no_main]
use arbitrary::Arbitrary;
use core::cmp::Ordering;
use libfuzzer_sys::fuzz_target;
use soroban_sdk::arbitrary::{
arbitrary, SorobanArbitrary,
};
use soroban_sdk::testutils::{Compare, Tag};
use soroban_sdk::xdr::ScVal;
use soroban_sdk::Env;
use soroban_sdk::RawVal;
use soroban_sdk::{FromVal, TryFromVal};
#[derive(Arbitrary, Debug)]
struct Test {
rawval_proto_1: <RawVal as SorobanArbitrary>::Prototype,
rawval_proto_2: <RawVal as SorobanArbitrary>::Prototype,
}
fuzz_target!(|input: Test| {
let Test {
rawval_proto_1,
rawval_proto_2,
} = input;
let env = &Env::default();
let budget = env.budget().0;
let rawval_1 = RawVal::from_val(env, &rawval_proto_1);
let rawval_2 = RawVal::from_val(env, &rawval_proto_2);
let (scval_1, scval_2) = {
let scval_1 = ScVal::try_from_val(env, &rawval_1);
let scval_2 = ScVal::try_from_val(env, &rawval_2);
let scval_1 = match scval_1 {
Ok(scval_1) => scval_1,
Err(e) => {
if rawval_1.get_tag() == Tag::Bad {
return;
}
panic!(
"couldn't convert rawval to scval:\n\
{rawval_1:?},\n\
{e:#?}"
);
}
};
let scval_2 = match scval_2 {
Ok(scval_2) => scval_2,
Err(e) => {
if rawval_2.get_tag() == Tag::Bad {
return;
}
panic!(
"couldn't convert rawval to scval:\n\
{rawval_2:?},\n\
{e:#?}"
);
}
};
(scval_1, scval_2)
};
// Check the comparison functions
{
let rawval_cmp = env.compare(&rawval_1, &rawval_2);
let rawval_cmp = rawval_cmp.expect("cmp");
let scval_cmp = Ord::cmp(&scval_1, &scval_2);
let rawval_cmp_is_eq = rawval_cmp == Ordering::Equal;
if rawval_cmp != scval_cmp {
panic!(
"rawval and scval don't compare the same:\n\
{rawval_1:#?}\n\
{rawval_2:#?}\n\
{rawval_cmp:#?}\n\
{scval_1:#?}\n\
{scval_2:#?}\n\
{scval_cmp:#?}"
);
}
let scval_cmp_partial = PartialOrd::partial_cmp(&scval_1, &scval_2);
assert_eq!(Some(scval_cmp), scval_cmp_partial);
let scval_partial_eq = PartialEq::eq(&scval_1, &scval_2);
assert_eq!(rawval_cmp_is_eq, scval_partial_eq);
// Compare<ScVal> for Budget
let scval_budget_cmp = budget.compare(&scval_1, &scval_2);
let scval_budget_cmp = scval_budget_cmp.expect("cmp");
if rawval_cmp != scval_budget_cmp {
panic!(
"rawval and scval (budget) don't compare the same:\n\
{rawval_1:#?}\n\
{rawval_2:#?}\n\
{rawval_cmp:#?}\n\
{scval_1:#?}\n\
{scval_2:#?}\n\
{scval_budget_cmp:#?}"
);
}
}
// Roundtrip checks
{
let rawval_after_1 = RawVal::try_from_val(env, &scval_1);
let rawval_after_1 = match rawval_after_1 {
Ok(rawval_after_1) => rawval_after_1,
Err(e) => {
panic!(
"couldn't convert scval to rawval:\n\
{scval_1:?},\n\
{e:#?}"
);
}
};
let rawval_cmp_before_after_1 = env.compare(&rawval_1, &rawval_after_1).expect("compare");
assert_eq!(rawval_cmp_before_after_1, Ordering::Equal);
let rawval_after_2 = RawVal::try_from_val(env, &scval_2);
let rawval_after_2 = match rawval_after_2 {
Ok(rawval_after_2) => rawval_after_2,
Err(e) => {
panic!(
"couldn't convert scval to rawval:\n\
{scval_2:?},\n\
{e:#?}"
);
}
};
let rawval_cmp_before_after_2 = env.compare(&rawval_2, &rawval_after_2).expect("compare");
assert_eq!(rawval_cmp_before_after_2, Ordering::Equal);
}
});