xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/qr_code-2.0.0/src/fuzz.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 use crate::decode::BmpDecode;
2 use crate::structured::{merge_qrs, SplittedQr};
3 use crate::{QrCode, Version};
4 
5 impl arbitrary::Arbitrary for QrCode {
arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self>6     fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
7         let level = crate::EcLevel::arbitrary(u)?;
8         let version = crate::Version::arbitrary(u)?;
9         let data = <Vec<u8>>::arbitrary(u)?;
10         let qr_code = QrCode::with_version(data, version, level)
11             .map_err(|_| arbitrary::Error::IncorrectFormat)?;
12         Ok(qr_code)
13     }
14 }
15 
16 #[derive(Debug)]
17 /// doc
18 pub struct QrCodeData {
19     /// qr
20     pub qr_code: QrCode,
21     /// data
22     pub data: Vec<u8>,
23     /// mul
24     pub mul_border: Option<(u8, u8)>,
25 }
26 
27 impl QrCodeData {
28     /// used for fuzz tests
check(self)29     pub fn check(self) {
30         let crate::QrCodeData {
31             qr_code,
32             data,
33             mul_border,
34         } = self;
35         let base_bmp = qr_code.to_bmp();
36         let bmp = match mul_border {
37             None => base_bmp,
38             Some((mul, border)) => base_bmp
39                 .mul(mul)
40                 .and_then(|mul_bmp| mul_bmp.add_white_border(border))
41                 .unwrap_or(base_bmp)
42                 .normalize(),
43         };
44         let decoded = bmp.decode().unwrap();
45         assert_eq!(data, decoded);
46     }
47 }
48 
49 impl arbitrary::Arbitrary for QrCodeData {
arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self>50     fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
51         let level = crate::EcLevel::arbitrary(u)?;
52         let version = crate::Version::arbitrary(u)?;
53         let data = <Vec<u8>>::arbitrary(u)?;
54         let qr_code = QrCode::with_version(&data, version, level)
55             .map_err(|_| arbitrary::Error::IncorrectFormat)?;
56         let mul_border = u8::arbitrary(u)?;
57         let mul_border = if mul_border % 2 == 0 {
58             None
59         } else {
60             Some(((mul_border / 64) + 2, (mul_border % 64) + 1))
61         };
62 
63         Ok(QrCodeData {
64             qr_code,
65             data,
66             mul_border,
67         })
68     }
69 }
70 
71 impl arbitrary::Arbitrary for Version {
arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self>72     fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
73         let v = u8::arbitrary(u)?;
74         match v {
75             1..=40 => Ok(Version::Normal(v as i16)),
76             //41..=44 => Ok(Version::Micro((v-40u8) as i16)),  not supported for now
77             _ => Err(arbitrary::Error::IncorrectFormat),
78         }
79     }
80 }
81 
82 /// split merge round-trip for fuzz testing
split_merge_rt(version: i16, bytes: Vec<u8>)83 pub fn split_merge_rt(version: i16, bytes: Vec<u8>) {
84     if let Ok(splitted_qr) = SplittedQr::new(bytes.clone(), version) {
85         if let Ok(qrs) = splitted_qr.split() {
86             //println!("qrs len:{}", qrs.len());
87             let mut vec = vec![];
88             for qr in qrs {
89                 let decoded = qr.to_bmp().decode().unwrap();
90                 vec.push(decoded);
91             }
92             if let Ok(merged) = merge_qrs(vec) {
93                 assert_eq!(merged, bytes);
94             }
95         }
96     }
97 }
98 
99 #[cfg(test)]
100 mod tests {
101     use crate::fuzz::split_merge_rt;
102 
103     #[test]
test_fuzz_decode_check()104     fn test_fuzz_decode_check() {
105         use arbitrary::Arbitrary;
106         let data = include_bytes!(
107             "../fuzz/artifacts/decode_check/crash-045dc09e6d00cfd6d3b3e9a4cfe5835e410c5fd1"
108         );
109         let unstructured = arbitrary::Unstructured::new(&data[..]);
110         let qr_code_data = crate::QrCodeData::arbitrary_take_rest(unstructured).unwrap();
111         qr_code_data.check();
112     }
113 
114     #[test]
test_fuzz_encode()115     fn test_fuzz_encode() {
116         let data = include_bytes!(
117             "../fuzz/artifacts/encode/crash-9ffe42701f80d18e9c114f1134b9d64045f7d5ce"
118         );
119         assert!(crate::QrCode::new(data).is_ok());
120     }
121 
122     #[test]
test_fuzz_split_merge_rt()123     fn test_fuzz_split_merge_rt() {
124         use arbitrary::Arbitrary;
125         let data = include_bytes!(
126             "../fuzz/artifacts/split_merge_rt/crash-1e272488adbe45a04a14b1a2b848997ff64e1b74"
127         );
128         let unstructured = arbitrary::Unstructured::new(&data[..]);
129         let (version, bytes) = <(i16, Vec<u8>)>::arbitrary_take_rest(unstructured).unwrap();
130         split_merge_rt(version, bytes);
131     }
132 }
133