aboutsummaryrefslogtreecommitdiff
path: root/fuzz/fuzz_targets/dav.rs
diff options
context:
space:
mode:
Diffstat (limited to 'fuzz/fuzz_targets/dav.rs')
-rw-r--r--fuzz/fuzz_targets/dav.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/fuzz/fuzz_targets/dav.rs b/fuzz/fuzz_targets/dav.rs
new file mode 100644
index 0000000..7549a03
--- /dev/null
+++ b/fuzz/fuzz_targets/dav.rs
@@ -0,0 +1,48 @@
+#![no_main]
+
+use libfuzzer_sys::fuzz_target;
+use aerogramme::dav::{types, realization, xml};
+use quick_xml::reader::NsReader;
+use tokio::runtime::Runtime;
+use tokio::io::AsyncWriteExt;
+
+async fn serialize(elem: &impl xml::QWrite) -> Vec<u8> {
+ let mut buffer = Vec::new();
+ let mut tokio_buffer = tokio::io::BufWriter::new(&mut buffer);
+ let q = quick_xml::writer::Writer::new_with_indent(&mut tokio_buffer, b' ', 4);
+ let ns_to_apply = vec![ ("xmlns:D".into(), "DAV:".into()) ];
+ let mut writer = xml::Writer { q, ns_to_apply };
+
+ elem.qwrite(&mut writer).await.expect("xml serialization");
+ tokio_buffer.flush().await.expect("tokio buffer flush");
+
+ return buffer
+}
+
+type Object = types::Multistatus<realization::Core, types::PropValue<realization::Core>>;
+
+fuzz_target!(|data: &[u8]| {
+ let rt = Runtime::new().expect("tokio runtime initialization");
+
+ rt.block_on(async {
+ // 1. Setup fuzzing by finding an input that seems correct, do not crash yet then.
+ let mut rdr = match xml::Reader::new(NsReader::from_reader(data)).await {
+ Err(_) => return,
+ Ok(r) => r,
+ };
+ let reference = match rdr.find::<Object>().await {
+ Err(_) => return,
+ Ok(m) => m,
+ };
+
+ // 2. Re-serialize the input
+ let my_serialization = serialize(&reference).await;
+
+ // 3. De-serialize my serialization
+ let mut rdr2 = xml::Reader::new(NsReader::from_reader(my_serialization.as_slice())).await.expect("XML Reader init");
+ let comparison = rdr2.find::<Object>().await.expect("Deserialize again");
+
+ // 4. Both the first decoding and last decoding must be identical
+ assert_eq!(reference, comparison);
+ })
+});