diff --git a/Cargo.toml b/Cargo.toml index 0ec4c5db34e7cd1d07d13261e8ec0121590a1704..30822b32fa82784ab48ea73b882fb53cc68fc4f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,6 @@ bitvec = { version = "1.0.1", default-features = false } crc = "3.0.1" encoding_rs = { version = "0.8.33", default-features = false } half = { version = "2.3.1", default-features = false } -labrador-ldpc = "1.1" +labrador-ldpc = { git = "https://github.com/adamgreig/labrador-ldpc" } paste = "1.0.14" snafu = { version = "0.7.5", default-features = false } diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 3093e731f415e7a084a0ce5eb23731c29c721e11..0e8f99a185eb82f3cfc26007c1431793d6f99a7d 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -96,7 +96,7 @@ dependencies = [ [[package]] name = "ham-cats" -version = "0.1.0" +version = "0.2.0" dependencies = [ "arrayvec", "bitvec", @@ -133,9 +133,7 @@ dependencies = [ [[package]] name = "labrador-ldpc" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ff4a0568f6322b64e06b6a6a0810e2f64670aa325f6e9dca24084e99917f459" +version = "1.1.1" [[package]] name = "libc" diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index bdfaa004d1686120c248706fdf3d1d8b18e47ce2..7884a306c6025b562ff610f87642233c2d793f5a 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -30,9 +30,14 @@ path = "fuzz_targets/fuzz_target_2.rs" test = false doc = false - [[bin]] name = "fuzz_target_3" path = "fuzz_targets/fuzz_target_3.rs" test = false doc = false + +[[bin]] +name = "fuzz_target_4" +path = "fuzz_targets/fuzz_target_4.rs" +test = false +doc = false diff --git a/fuzz/fuzz_targets/fuzz_target_4.rs b/fuzz/fuzz_targets/fuzz_target_4.rs new file mode 100644 index 0000000000000000000000000000000000000000..c1482c68944adef29e0b4882e97b93afe4a5ff61 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_target_4.rs @@ -0,0 +1,16 @@ +#![no_main] +use libfuzzer_sys::fuzz_target; + +use ham_cats::packet::Packet; +use std::convert::TryInto; + +fuzz_target!(|data: &[u8]| { + // [u8] -> [i8] + let mut data: Vec<_> = data + .iter() + .map(|x| (u16::from(*x) as i16 - 128).try_into().unwrap()) + .collect(); + + let mut buf = [0; 1024]; + let _ = Packet::<1024>::fully_decode_soft::<8192, i8>(&mut data, &mut buf); +}); diff --git a/src/interleaver.rs b/src/interleaver.rs index e6386968ca7868cc31b24fe4b018dd427b1db715..e909ad41a6c1e0135252950bce9beb8cd51ffdd7 100644 --- a/src/interleaver.rs +++ b/src/interleaver.rs @@ -87,9 +87,8 @@ pub(crate) fn uninterleave_soft<const N: usize, T: DecodeFrom>( #[cfg(test)] mod tests { - use crate::soft_bit::SoftBit; - use super::*; + use crate::soft_bit::FromHardBit; #[test] fn interleaver_works() { diff --git a/src/ldpc.rs b/src/ldpc.rs index b51a87795a848e2ed497bb21580394f7e604c1b9..65989365e439b104558e026f86dccfb293eb06b9 100644 --- a/src/ldpc.rs +++ b/src/ldpc.rs @@ -1,6 +1,6 @@ use labrador_ldpc::{decoder::DecodeFrom, LDPCCode}; -use crate::{buffer::Buffer, error::EncodeError, soft_bit::SoftBit}; +use crate::{buffer::Buffer, error::EncodeError}; macro_rules! enc_chunk { ($d:ident, $i:ident, $t:ident, $n:literal) => { @@ -188,12 +188,14 @@ pub(crate) fn decode_soft<const N: usize, const M: usize, T: DecodeFrom>( let len: usize = len_from_soft(data_av[(data_av.len() - 16)..].try_into().unwrap()).into(); - if len * 8 >= data_av.len() { + if len * 8 + 16 >= data_av.len() { return None; } - let (mut data, parity) = data_av.split_at_mut(len * 8); - let mut parity = parity.get_mut(..parity.len().checked_sub(16)?)?; + let data_len = data_av.len().checked_sub(16)?; + let data_av = data_av.get_mut(..data_len)?; + + let (mut data, mut parity) = data_av.split_at_mut(len * 8); let mut working = [T::zero(); LDPCCode::TM8192.decode_ms_working_len()]; let mut working_u8 = [0; LDPCCode::TM8192.decode_ms_working_u8_len()]; @@ -276,9 +278,9 @@ fn len_from_soft<T: DecodeFrom>(bits: &[T; 16]) -> u16 { #[cfg(test)] mod tests { - use bitvec::{order::Msb0, view::BitView}; - use super::*; + use crate::soft_bit::FromHardBit; + use bitvec::{order::Msb0, view::BitView}; #[test] fn len_test() { diff --git a/src/packet.rs b/src/packet.rs index 13f9db32c460e1c3f5074d6bd59364f40db0ff34..27b1278d1140f3c1be98c7781052fd91ab164964 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -407,13 +407,12 @@ fn try_lock<'a, const N: usize, T, E, F: Fn(&mut Buffer<'a, N>) -> Result<T, E>> #[cfg(test)] mod tests { + use super::*; + use crate::soft_bit::FromHardBit; + use crate::whisker::NodeInfoBuilder; use arrayvec::ArrayString; use bitvec::{order::Msb0, view::BitView}; - use crate::{soft_bit::SoftBit, whisker::NodeInfoBuilder}; - - use super::*; - #[test] fn dest() { let d1 = Destination::new(false, 7, "CALL1", 23).unwrap(); @@ -789,4 +788,31 @@ mod tests { let _ = Packet::<1024>::decode(buf); } } + + #[test] + fn fully_decode_soft_fuzz_tests() { + // When adding to this, don't forget to do the u8 -> i8 conversion + let cases = [ + &mut [ + -39, -39, -39, -118, -58, -58, -58, -58, -89, -39, -118, -58, -58, -58, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -58, -58, + 127, 81, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -86, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -58, -58, 127, + 81, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, -58, -58, 127, 81, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, -128, -128, -128, -128, -128, -128, -128, -128, -128, + -128, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -128, -128, + ][..], + &mut [ + -73, -73, -73, -73, -75, -76, -73, -73, -73, -73, -73, -73, -73, -73, 73, 72, 72, + 72, 72, 72, 72, 62, -73, -118, 120, 127, 127, 121, 127, 112, 127, 127, + ], + ]; + + for data in cases { + let mut buf = [0; 1024]; + let _ = Packet::<1024>::fully_decode_soft::<8192, i8>(data, &mut buf); + } + } } diff --git a/src/soft_bit.rs b/src/soft_bit.rs index d2165885e70439f4e3e3e6738d219fce1a57884e..11e9bb2a0d4475c48ff90bed1de99f538c3aaa2f 100644 --- a/src/soft_bit.rs +++ b/src/soft_bit.rs @@ -2,12 +2,11 @@ pub use labrador_ldpc::decoder::DecodeFrom; // Less than zero = 1 bit // Greater than zero = 0 bit -pub trait SoftBit { +pub trait FromHardBit { fn from_hard_bit(bit: bool) -> Self; - fn hard_bit(&self) -> bool; } -impl<T: DecodeFrom> SoftBit for T { +impl<T: DecodeFrom> FromHardBit for T { fn from_hard_bit(bit: bool) -> Self { if bit { -Self::one() @@ -15,10 +14,6 @@ impl<T: DecodeFrom> SoftBit for T { Self::one() } } - - fn hard_bit(&self) -> bool { - self < &T::zero() - } } #[cfg(test)]