1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use flexbuffers::*;
16 #[cfg(not(miri))]  // slow.
17 use quickcheck::QuickCheck;
18 
19 #[test]
20 #[cfg(not(miri))]  // slow.
qc_reader_no_crash()21 fn qc_reader_no_crash() {
22     fn no_crash(xs: Vec<u8>) -> bool {
23         let r = Reader::get_root(xs.as_ref());
24         r.is_err() || r.is_ok()
25     }
26     QuickCheck::new()
27         .min_tests_passed(10_000_000)
28         .quicktest(no_crash as fn(Vec<u8>) -> bool)
29         .unwrap();
30 
31     no_crash(vec![0, 10 << 2 | 2, 0]);
32 }
33 #[test]
as_num()34 fn as_num() {
35     let mut fxb = Builder::default();
36     let mut m = fxb.start_map();
37     m.push("a", &[-1i8, -2, -3, -4]);
38     m.push("b", 250i64);
39     m.push("c", 5000u16);
40     m.end_map();
41 
42     let r = Reader::get_root(fxb.view()).unwrap();
43     assert_eq!(r.as_i8(), 3); // length.
44     assert_eq!(r.as_i16(), 3);
45     assert_eq!(r.as_i32(), 3);
46     assert_eq!(r.as_i64(), 3);
47     assert_eq!(r.as_u8(), 3);
48     assert_eq!(r.as_u16(), 3);
49     assert_eq!(r.as_u32(), 3);
50     assert_eq!(r.as_u64(), 3);
51     assert_eq!(r.as_f32(), 3.0);
52     assert_eq!(r.as_f64(), 3.0);
53 
54     let m = r.as_map();
55     let a = m.index("a").unwrap();
56     assert_eq!(a.as_f32(), 4.0); // length.
57     assert_eq!(a.as_f64(), 4.0); // length.
58     assert_eq!(a.as_vector().idx(0).as_i8(), -1);
59     assert_eq!(a.as_vector().idx(1).as_i16(), -2);
60     assert_eq!(a.as_vector().idx(2).as_i32(), -3);
61     assert_eq!(a.as_vector().idx(3).as_i64(), -4);
62 
63     let b = m.index("b").unwrap();
64     assert_eq!(b.as_u8(), 250);
65     assert_eq!(b.as_u16(), 250);
66     assert_eq!(b.as_u32(), 250);
67     assert_eq!(b.as_u64(), 250);
68     assert_eq!(b.as_i8(), 0); // overflow
69     assert_eq!(b.as_i16(), 250);
70     assert_eq!(b.as_i32(), 250);
71     assert_eq!(b.as_i64(), 250);
72 
73     let c = m.index("c").unwrap();
74     assert_eq!(c.as_i64(), 5000);
75     assert_eq!(c.as_u64(), 5000);
76     assert_eq!(c.as_f32(), 5000.0);
77     assert_eq!(c.as_u8(), 0); // overflow
78     assert_eq!(c.as_u16(), 5000);
79     assert_eq!(c.as_u32(), 5000);
80     assert_eq!(c.as_u64(), 5000);
81     assert_eq!(c.as_i8(), 0); // overflow
82     assert_eq!(c.as_i16(), 5000);
83     assert_eq!(c.as_i32(), 5000);
84     assert_eq!(c.as_i64(), 5000);
85 }
86 #[test]
string_as_num()87 fn string_as_num() {
88     let mut fxb = Builder::default();
89     let mut v = fxb.start_vector();
90     v.push("3.1415");
91     v.push("9.001e3");
92     v.push("42");
93     v.end_vector();
94     let r = Reader::get_root(fxb.view()).unwrap();
95 
96     let v0 = r.as_vector().idx(0);
97     assert_eq!(v0.as_f64(), 3.1415);
98     assert_eq!(v0.as_f32(), 3.1415);
99     assert_eq!(v0.as_u8(), 0);
100     assert_eq!(v0.as_u16(), 0);
101     assert_eq!(v0.as_u32(), 0);
102     assert_eq!(v0.as_u64(), 0);
103     assert_eq!(v0.as_i8(), 0);
104     assert_eq!(v0.as_i16(), 0);
105     assert_eq!(v0.as_i32(), 0);
106     assert_eq!(v0.as_i64(), 0);
107 
108     let v1 = r.as_vector().idx(1);
109     assert_eq!(v1.as_f64(), 9001.0);
110     assert_eq!(v1.as_f32(), 9001.0);
111     assert_eq!(v1.as_u8(), 0);
112     assert_eq!(v1.as_u16(), 0);
113     assert_eq!(v1.as_u32(), 0);
114     assert_eq!(v1.as_u64(), 0);
115     assert_eq!(v1.as_i8(), 0);
116     assert_eq!(v1.as_i16(), 0);
117     assert_eq!(v1.as_i32(), 0);
118     assert_eq!(v1.as_i64(), 0);
119     assert_eq!(v1.as_i32(), 0);
120 
121     let v2 = r.as_vector().idx(2);
122     assert_eq!(v2.as_f64(), 42.0);
123     assert_eq!(v2.as_f32(), 42.0);
124     assert_eq!(v2.as_u8(), 42);
125     assert_eq!(v2.as_u16(), 42);
126     assert_eq!(v2.as_u32(), 42);
127     assert_eq!(v2.as_u64(), 42);
128     assert_eq!(v2.as_i8(), 42);
129     assert_eq!(v2.as_i16(), 42);
130     assert_eq!(v2.as_i32(), 42);
131     assert_eq!(v2.as_i64(), 42);
132     assert_eq!(v2.as_i32(), 42);
133 }
134 #[test]
null_reader()135 fn null_reader() {
136     let n = Reader::<&[u8]>::default();
137     assert_eq!(n.as_i8(), 0);
138     assert_eq!(n.as_i16(), 0);
139     assert_eq!(n.as_i32(), 0);
140     assert_eq!(n.as_i64(), 0);
141     assert_eq!(n.as_u8(), 0);
142     assert_eq!(n.as_u16(), 0);
143     assert_eq!(n.as_u32(), 0);
144     assert_eq!(n.as_u64(), 0);
145     assert_eq!(n.as_f32(), 0.0);
146     assert_eq!(n.as_f64(), 0.0);
147     assert!(n.get_i64().is_err());
148     assert!(n.get_u64().is_err());
149     assert!(n.get_f64().is_err());
150     assert!(n.as_vector().is_empty());
151     assert!(n.as_map().is_empty());
152     assert_eq!(n.as_vector().idx(1).flexbuffer_type(), FlexBufferType::Null);
153     assert_eq!(n.as_map().idx("1").flexbuffer_type(), FlexBufferType::Null);
154 }
155 #[test]
get_root_deref_oob()156 fn get_root_deref_oob() {
157     let s = &[
158         4, // Deref out of bounds
159         (FlexBufferType::Vector as u8) << 2 | BitWidth::W8 as u8,
160         1,
161     ];
162     assert!(Reader::get_root(s.as_ref()).is_err());
163 }
164 #[test]
get_root_deref_u64()165 fn get_root_deref_u64() {
166     let s = &[
167         0,
168         0,
169         (FlexBufferType::IndirectUInt as u8) << 2 | BitWidth::W64 as u8,
170         1,
171     ];
172     // The risk of crashing is reading 8 bytes from index 0.
173     assert_eq!(Reader::get_root(s.as_ref()).unwrap().as_u64(), 0);
174 }
175 
176 /// Verifies that the clone operation is shallow / zero copy.
177 #[test]
clone_is_shallow()178 fn clone_is_shallow() {
179     let mut fxb = Builder::default();
180     let mut m = fxb.start_map();
181     m.push("a", &[-1i8, -2, -3, -4]);
182     m.push("b", 250i64);
183     m.push("c", 5000u16);
184     m.end_map();
185 
186     let r = Reader::get_root(fxb.view()).unwrap();
187 
188     let r2 = r.clone();
189 
190     assert_eq!(r.buffer().as_ptr(), r2.buffer().as_ptr());
191 }
192 
193 #[test]
194 #[should_panic]
build_map_panic_on_repeated_key()195 fn build_map_panic_on_repeated_key() {
196     let mut b = Builder::default();
197     let mut m = b.start_map();
198     m.push("foo", 5u8);
199     m.push("foo", 6u8);
200     m.end_map();
201 }
202 #[test]
203 #[should_panic]
build_map_panic_on_internal_null()204 fn build_map_panic_on_internal_null() {
205     let mut b = Builder::default();
206     let mut m = b.start_map();
207     m.push("foo\0", 5u8);
208     m.end_map();
209 }
210