| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #![no_main] |
| use libfuzzer_sys::fuzz_target; |
| |
| use serde::{Deserialize, Serialize}; |
| |
| #[derive(Debug, Serialize, Deserialize, PartialEq)] |
| enum PlainEnum { |
| A, |
| B, |
| C, |
| D, |
| } |
| |
| #[derive(Debug, Serialize, Deserialize, PartialEq)] |
| enum Enum { |
| A(u8), |
| B(()), |
| C(Vec<PlainEnum>), |
| D(i128), |
| } |
| |
| #[derive(Debug, Serialize, Deserialize, PartialEq)] |
| enum FloatEnum { |
| A(Enum), |
| E(Option<f32>), |
| } |
| |
| #[derive(Debug, Serialize, Deserialize, PartialEq)] |
| struct Struct { |
| _a: (), |
| _b: u8, |
| _c: Vec<Enum>, |
| _d: (u128, i8, (), PlainEnum, String), |
| } |
| |
| #[derive(Debug, Serialize, Deserialize, PartialEq)] |
| struct FloatStruct { |
| _a: Struct, |
| _b: f64, |
| } |
| |
| macro_rules! round_trip { |
| ($ty:ty, $data:ident, $equality:expr) => {{ |
| #[cfg(feature = "debug")] |
| println!("roundtripping {}", stringify!($ty)); |
| |
| use ::apache_avro::{from_value, Reader}; |
| |
| let reader = match Reader::new($data) { |
| Ok(r) => r, |
| _ => return, |
| }; |
| |
| for value in reader { |
| let value = match value { |
| Ok(v) => v, |
| _ => continue, |
| }; |
| #[cfg(feature = "debug")] |
| println!("value {:?}", &value); |
| |
| let _: Result<$ty, _> = from_value(&value); |
| } |
| }}; |
| } |
| |
| macro_rules! from_bytes { |
| ($ty:ty, $data:ident, $equality:expr) => {{ |
| round_trip!($ty, $data, $equality); |
| round_trip!(Vec<$ty>, $data, $equality); |
| round_trip!(Option<$ty>, $data, $equality); |
| }}; |
| } |
| |
| fuzz_target!(|data: &[u8]| { |
| // limit avro memory usage |
| apache_avro::max_allocation_bytes(2 * 1024 * 1024); // 2 MB |
| |
| from_bytes!(bool, data, true); |
| from_bytes!(i8, data, true); |
| from_bytes!(i16, data, true); |
| from_bytes!(i32, data, true); |
| from_bytes!(i64, data, true); |
| from_bytes!(i128, data, true); |
| from_bytes!(u8, data, true); |
| from_bytes!(u16, data, true); |
| from_bytes!(u32, data, true); |
| from_bytes!(u64, data, true); |
| from_bytes!(u128, data, true); |
| from_bytes!(f32, data, false); |
| from_bytes!(f64, data, false); |
| from_bytes!(char, data, true); |
| from_bytes!(&str, data, true); |
| from_bytes!((), data, true); |
| from_bytes!(PlainEnum, data, true); |
| from_bytes!(Enum, data, true); |
| from_bytes!(FloatEnum, data, false); |
| from_bytes!(Struct, data, true); |
| from_bytes!(FloatStruct, data, false); |
| }); |