Files
2026-07-09 05:08:16 +08:00

61 lines
1.8 KiB
Rust

/*!
Fuzz target for `ferro_ta_core::overlap::bbands`.
Verifies that BBANDS never panics and that the three output vectors
(upper, middle, lower) always have the same length as the input.
When finite, upper >= middle >= lower must hold.
*/
#![no_main]
use libfuzzer_sys::fuzz_target;
use ferro_ta_core::overlap;
fuzz_target!(|data: &[u8]| {
if data.len() < 3 {
return;
}
let timeperiod = ((data[0] as usize) % 64) + 1;
// Use second byte for deviation multipliers (1.0 - 4.0 range)
let nbdevup = 1.0 + (data[1] as f64 / 255.0) * 3.0;
let nbdevdn = 1.0 + (data[2] as f64 / 255.0) * 3.0;
let float_bytes = &data[3..];
let n_floats = float_bytes.len() / 8;
if n_floats == 0 {
return;
}
let close: Vec<f64> = (0..n_floats)
.map(|i| {
let chunk: [u8; 8] = float_bytes[i * 8..(i + 1) * 8].try_into().unwrap();
f64::from_le_bytes(chunk)
})
.collect();
let (upper, middle, lower) = overlap::bbands(&close, timeperiod, nbdevup, nbdevdn);
assert_eq!(upper.len(), close.len(), "BBANDS upper length mismatch");
assert_eq!(middle.len(), close.len(), "BBANDS middle length mismatch");
assert_eq!(lower.len(), close.len(), "BBANDS lower length mismatch");
// When all three are finite, upper >= middle >= lower
for i in 0..close.len() {
if upper[i].is_finite() && middle[i].is_finite() && lower[i].is_finite() {
assert!(
upper[i] >= middle[i],
"BBANDS upper[{i}] ({}) < middle[{i}] ({})",
upper[i],
middle[i]
);
assert!(
middle[i] >= lower[i],
"BBANDS middle[{i}] ({}) < lower[{i}] ({})",
middle[i],
lower[i]
);
}
}
});