Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions fuzz/fuzz_targets/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ pub struct FuzzInput<C> {

impl<C: std::fmt::Debug> std::fmt::Debug for FuzzInput<C> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FuzzInput<C>")
.field("data_length", &self.data.len())
f.debug_struct("FuzzInput")
.field("codec", &self.codec)
.field("data", &HexSlice(&self.data))
.finish()
}
}
Expand Down Expand Up @@ -117,3 +117,26 @@ impl From<CppCodec> for BoxedCppCodec {
}
}
}

pub struct HexSlice<'a>(pub &'a [u32]);

impl<'a> std::fmt::Debug for HexSlice<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
const MAX: usize = 20;

let total = self.0.len();
let shown = total.min(MAX);

let mut list = f.debug_list();

for v in &self.0[..shown] {
list.entry(&format_args!("{:#010x}", v));
}

if total > MAX {
list.entry(&format_args!(".. out of {} total", total));
}

list.finish()
}
}
15 changes: 5 additions & 10 deletions fuzz/fuzz_targets/rust_compress_oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ fuzz_target!(|data: FuzzInput<RustCodec>| {
return;
}

// TODO: Behaviour differs
if data.codec == RustCodec::VariableByte {
return;
}

// TODO: To make the encoder not crash -> Skip inputs smaller than block size
let block_size = match data.codec {
RustCodec::FastPFOR256 => 256,
Expand All @@ -44,7 +39,7 @@ fuzz_target!(|data: FuzzInput<RustCodec>| {
.expect("Rust compression failed");

// Compress with C++ implementation
let cpp_result = match data.codec {
let compressed_oracle_from_cpp = match data.codec {
RustCodec::FastPFOR256 => {
let mut cpp_codec = cpp::FastPFor256Codec::new();
cpp_codec
Expand All @@ -58,7 +53,7 @@ fuzz_target!(|data: FuzzInput<RustCodec>| {
.expect("C++ compression failed")
}
RustCodec::VariableByte => {
let mut cpp_codec = cpp::VByteCodec::new();
let mut cpp_codec = cpp::MaskedVByteCodec::new();
cpp_codec
.compress_to_slice(input, &mut cpp_compressed)
.expect("C++ compression failed")
Expand All @@ -74,13 +69,13 @@ fuzz_target!(|data: FuzzInput<RustCodec>| {
// Compare compressed outputs
assert_eq!(
rust_result.len(),
cpp_result.len(),
compressed_oracle_from_cpp.len(),
"Compressed length mismatch: Rust={}, C++={}",
rust_result.len(),
cpp_result.len()
compressed_oracle_from_cpp.len()
);

for (i, (&rust_val, &cpp_val)) in rust_result.iter().zip(cpp_result.iter()).enumerate() {
for (i, (&rust_val, &cpp_val)) in rust_result.iter().zip(compressed_oracle_from_cpp.iter()).enumerate() {
assert_eq!(
rust_val, cpp_val,
"Compressed data mismatch at position {}: Rust={}, C++={}",
Expand Down
13 changes: 4 additions & 9 deletions fuzz/fuzz_targets/rust_decompress_oracle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![no_main]

use fastpfor::{CodecToSlice, cpp, rust};
use fastpfor::{cpp, rust, CodecToSlice};
use libfuzzer_sys::fuzz_target;
mod common;
use common::*;
Expand All @@ -13,11 +13,6 @@ fuzz_target!(|data: FuzzInput<RustCodec>| {
return;
}

// TODO: Behaviour differs
if data.codec == RustCodec::VariableByte {
return;
}

// TODO: To make the decoder not crash -> Skip inputs smaller than block size
let block_size = match data.codec {
RustCodec::FastPFOR256 => 256,
Expand All @@ -35,7 +30,7 @@ fuzz_target!(|data: FuzzInput<RustCodec>| {

// First, compress with C++ implementation to get valid compressed data
let mut cpp_compressed = vec![0u32; input.len() * 2 + 1024];
let compressed_data = match data.codec {
let compressed_oracle_from_cpp = match data.codec {
RustCodec::FastPFOR256 => {
let mut cpp_codec = cpp::FastPFor256Codec::new();
cpp_codec
Expand All @@ -49,7 +44,7 @@ fuzz_target!(|data: FuzzInput<RustCodec>| {
.expect("C++ compression failed")
}
RustCodec::VariableByte => {
let mut cpp_codec = cpp::VByteCodec::new();
let mut cpp_codec = cpp::MaskedVByteCodec::new();
cpp_codec
.compress_to_slice(input, &mut cpp_compressed)
.expect("C++ compression failed")
Expand All @@ -66,7 +61,7 @@ fuzz_target!(|data: FuzzInput<RustCodec>| {
let mut rust_decompressed = vec![0u32; input.len()];
let mut rust_codec = rust::Codec::from(data.codec);
let rust_result = rust_codec
.decompress_to_slice(compressed_data, &mut rust_decompressed)
.decompress_to_slice(compressed_oracle_from_cpp, &mut rust_decompressed)
.expect("Rust decompression failed");

// Compare decompressed outputs
Expand Down
12 changes: 0 additions & 12 deletions src/rust/integer_compression/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,3 @@ fn bitlen(x: u64) -> i32 {
}
64 - clz(x) as i32
}

/// Extracts 7 bits from `val` at the position specified by `i` (0-indexed, each position is 7 bits).
/// The result is masked to ensure only 7 bits are returned.
pub fn extract7bits(i: i32, val: i64) -> u8 {
((val >> (7 * i)) & ((1 << 7) - 1)) as u8
}

/// Extracts 7 bits from `val` at the position specified by `i` without masking.
/// Caller must ensure proper masking if needed.
pub fn extract_7bits_maskless(i: i32, val: i64) -> u8 {
(val >> (7 * i)) as u8
}
Loading
Loading