Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
58 changes: 35 additions & 23 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#![feature(test)]

extern crate test;
extern crate lzxpress;
extern crate test;

use test::Bencher;

extern "C" {
fn decompress_lznt1(
fn decompress_lznt1(
in_buf: *const u8,
in_buf_max_size: i32,
out_buf: *mut u8,
out_buf_max_size: i32,
pout_buf_size: *mut i32
pout_buf_size: *mut i32,
) -> bool;
}

Expand All @@ -20,7 +20,7 @@ extern "C" {
fn bench_lznt1_decompress_rtl(b: &mut Bencher) {
let compression_format_lznt1 = 0x0002 as u16;
let compression_engine_standard = 0x0000 as u16;
use ntapi::ntrtl::{RtlDecompressBuffer};
use ntapi::ntrtl::RtlDecompressBuffer;

let compressed_data = include_bytes!("../tests/block1.compressed.bin");
let mut mutable_compressed_data = compressed_data.to_vec();
Expand All @@ -36,7 +36,14 @@ fn bench_lznt1_decompress_rtl(b: &mut Bencher) {
let mut dst = Vec::with_capacity(dstlen as usize);
let pdst = dst.as_mut_ptr();

let _ntstatus = RtlDecompressBuffer(compression_format_lznt1 | compression_engine_standard, pdst, dstlen, psrc, srclen, &mut dstlen2);
let _ntstatus = RtlDecompressBuffer(
compression_format_lznt1 | compression_engine_standard,
pdst,
dstlen,
psrc,
srclen,
&mut dstlen2,
);

dst.set_len(dstlen2 as usize);
};
Expand All @@ -48,22 +55,17 @@ fn bench_lznt1_decompress_cpp(b: &mut Bencher) {
let compressed_data = include_bytes!("../tests/block1.compressed.bin");

b.iter(|| {
let _ret = unsafe {
unsafe {
let psrc = compressed_data.as_ptr();
let srclen = compressed_data.len() as i32;

let dstlen = 0x100000;
let dstlen = 0x0010_0000;
let mut dstlen2: i32 = 0;

let mut dst = Vec::with_capacity(dstlen as usize);
let pdst = dst.as_mut_ptr();

let _status = decompress_lznt1(
psrc,
srclen,
pdst,
dstlen,
&mut dstlen2);
let _status = decompress_lznt1(psrc, srclen, pdst, dstlen, &mut dstlen2);
dst.set_len(dstlen2 as usize);
};
});
Expand All @@ -83,9 +85,9 @@ fn bench_lznt1_decompress2_push(b: &mut Bencher) {
let compressed_data = include_bytes!("../tests/block1.compressed.bin");

b.iter(|| {
let dstlen = 0x100000;
let dstlen = 0x0010_0000;
let mut out_buf: Vec<u8> = Vec::with_capacity(dstlen);
let _uncompressed = lzxpress::lznt1::decompress2_push(compressed_data, &mut out_buf).unwrap();
lzxpress::lznt1::decompress2_push(compressed_data, &mut out_buf).unwrap();
});
}

Expand All @@ -94,24 +96,25 @@ fn bench_lznt1_decompress2_no_push(b: &mut Bencher) {
let compressed_data = include_bytes!("../tests/block1.compressed.bin");

b.iter(|| {
let dstlen = 0x100000;
let dstlen = 0x0010_0000;
let mut out_buf: Vec<u8> = Vec::with_capacity(dstlen);
unsafe {
out_buf.set_len(dstlen);
}
let _uncompressed = lzxpress::lznt1::decompress2_no_push(compressed_data, &mut out_buf).unwrap();
lzxpress::lznt1::decompress2_no_push(compressed_data, &mut out_buf).unwrap();
});
}


#[bench]
#[cfg(windows)]
fn bench_lzxpress_decompress_rtl(b: &mut Bencher) {
let compression_format_xpress = 0x0003 as u16;
let compression_engine_standard = 0x0000 as u16;
use ntapi::ntrtl::{RtlDecompressBuffer};
use ntapi::ntrtl::RtlDecompressBuffer;

let compressed_data = include_bytes!("../tests/clusterfuzz-testcase-minimized-fuzz_ndr_drsuapi_TYPE_OUT-5724999789051904");
let compressed_data = include_bytes!(
"../tests/clusterfuzz-testcase-minimized-fuzz_ndr_drsuapi_TYPE_OUT-5724999789051904"
);
let mut mutable_compressed_data = compressed_data.to_vec();

b.iter(|| {
Expand All @@ -125,16 +128,25 @@ fn bench_lzxpress_decompress_rtl(b: &mut Bencher) {
let mut dst = Vec::with_capacity(dstlen as usize);
let pdst = dst.as_mut_ptr();

let _ntstatus = RtlDecompressBuffer(compression_format_xpress | compression_engine_standard, pdst, dstlen, psrc, srclen, &mut dstlen2);
let _ntstatus = RtlDecompressBuffer(
compression_format_xpress | compression_engine_standard,
pdst,
dstlen,
psrc,
srclen,
&mut dstlen2,
);
};
});
}

#[bench]
fn bench_lzxpress_decompress(b: &mut Bencher) {
let compressed_data = include_bytes!("../tests/clusterfuzz-testcase-minimized-fuzz_ndr_drsuapi_TYPE_OUT-5724999789051904");
let compressed_data = include_bytes!(
"../tests/clusterfuzz-testcase-minimized-fuzz_ndr_drsuapi_TYPE_OUT-5724999789051904"
);

b.iter(|| {
let _uncompressed = lzxpress::data::decompress(compressed_data);
});
}
}
6 changes: 2 additions & 4 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
extern crate cc;

fn main() {
cc::Build::new()
.file("tests/lznt1.c")
.compile("libfoo.a");
}
cc::Build::new().file("tests/lznt1.c").compile("libfoo.a");
}
115 changes: 52 additions & 63 deletions src/data.rs
Original file line number Diff line number Diff line change
@@ -1,48 +1,38 @@
use std::mem;
use std::cmp;
use std::mem;

pub use crate::error::Error;

macro_rules! store32le{
($dst:expr,$idx:expr,$val:expr)=>{
{
$dst[$idx + 0] = $val as u8;
$dst[$idx + 1] = ($val >> 8) as u8;
$dst[$idx + 2] = ($val >> 16) as u8;
$dst[$idx + 3] = ($val >> 24) as u8;
}
}
}

macro_rules! load16le{
($dst:expr,$src:expr,$idx:expr)=>{
{
$dst = (u32::from($src[$idx + 1]) << 8
| u32::from($src[$idx])) as usize;
}
}
macro_rules! store32le {
($dst:expr,$idx:expr,$val:expr) => {{
$dst[$idx + 0] = $val as u8;
$dst[$idx + 1] = ($val >> 8) as u8;
$dst[$idx + 2] = ($val >> 16) as u8;
$dst[$idx + 3] = ($val >> 24) as u8;
}};
}

macro_rules! load32le{
($dst:expr,$src:expr,$idx:expr)=>{
{
$dst = ((u32::from($src[$idx + 3]) << 24)
macro_rules! load16le {
($dst:expr,$src:expr,$idx:expr) => {{
$dst = (u32::from($src[$idx + 1]) << 8 | u32::from($src[$idx])) as usize;
}};
}

macro_rules! load32le {
($dst:expr,$src:expr,$idx:expr) => {{
$dst = ((u32::from($src[$idx + 3]) << 24)
| (u32::from($src[$idx + 2]) << 16)
| (u32::from($src[$idx + 1]) << 8)
| (u32::from($src[$idx + 1]) << 8)
| u32::from($src[$idx])) as usize;
}
}
}};
}

pub fn decompress(
in_buf: &[u8]
) -> Result<Vec<u8>, Error>
{
let mut out_idx: usize = 0;
let mut in_idx: usize = 0;
pub fn decompress(in_buf: &[u8]) -> Result<Vec<u8>, Error> {
let mut out_idx: usize = 0;
let mut in_idx: usize = 0;
let mut nibble_idx: usize = 0;

let mut flags: usize = 0;
let mut flags: usize = 0;
let mut flag_count: usize = 0;

let mut length: usize;
Expand Down Expand Up @@ -75,27 +65,32 @@ pub fn decompress(
in_idx += mem::size_of::<u8>();
out_idx += mem::size_of::<u8>();
} else {
if (in_idx + 1) >= in_buf.len() {
if in_idx == in_buf.len() {
// [MS-XCA] - v20210625, 2.4.4
break;
}

if (in_idx + 1) > in_buf.len() {
return Err(Error::MemLimit);
}

load16le!(length, in_buf, in_idx);
in_idx += mem::size_of::<u16>();

offset = (length / 8) + 1;
length = length % 8;
length %= 8;

if length == 7 {
if nibble_idx == 0 {
if in_idx >= in_buf.len() {
if in_idx > in_buf.len() {
return Err(Error::MemLimit);
}

length = (in_buf[in_idx] % 16).into();
nibble_idx = in_idx;
in_idx += mem::size_of::<u8>();
} else {
if nibble_idx >= in_buf.len() {
if nibble_idx > in_buf.len() {
return Err(Error::MemLimit);
}

Expand All @@ -104,15 +99,15 @@ pub fn decompress(
}

if length == 15 {
if in_idx >= in_buf.len() {
if in_idx > in_buf.len() {
return Err(Error::MemLimit);
}

length = in_buf[in_idx].into();
in_idx += mem::size_of::<u8>();

if length == 255 {
if (in_idx + 1) >= in_buf.len() {
if (in_idx + 1) > in_buf.len() {
return Err(Error::MemLimit);
}

Expand Down Expand Up @@ -149,29 +144,25 @@ pub fn decompress(
Ok(out_buf)
}

pub fn compress(
in_buf: &[u8]
) -> Result<Vec<u8>, Error>
{

let mut in_idx: usize = 0;
let mut out_idx: usize;
pub fn compress(in_buf: &[u8]) -> Result<Vec<u8>, Error> {
let mut in_idx: usize = 0;
let mut out_idx: usize;
let mut byte_left: usize;

let mut max_off: usize;
let mut max_off: usize;
let mut match_off: usize;

let mut max_len: usize;
let mut max_len: usize;
let mut best_len: usize;

let mut flags: u32 = 0;
let mut flag_count: u32 = 0;
let mut flags: u32 = 0;
let mut flag_count: u32 = 0;
let mut flag_out_off: usize = 0;
let mut nibble_index: usize = 0;

let mut metadata_size: usize;
let mut metadata: usize;
let mut _dest_off: usize;
let mut metadata: usize;
let mut _dest_off: usize;

let mut str1_off: usize;
let mut str2_off: usize;
Expand Down Expand Up @@ -247,7 +238,7 @@ pub fn compress(

if match_len < 7 {
// Classical meta-data
metadata = (match_off << 3) + match_len;
metadata = (match_off << 3) + match_len;
out_buf.push(metadata as u8);
out_buf.push((metadata >> 8) as u8);
metadata_size += mem::size_of::<u16>();
Expand All @@ -272,23 +263,21 @@ pub fn compress(

has_extra_len = true;
}
} else if match_len < 15 {
out_buf[nibble_index] |= (match_len << 4) as u8;
nibble_index = 0;
} else {
if match_len < 15 {
out_buf[nibble_index] |= (match_len << 4) as u8;
nibble_index = 0;
} else {
out_buf[nibble_index] |= (15 << 4) as u8;
nibble_index = 0;
out_buf[nibble_index] |= (15 << 4) as u8;
nibble_index = 0;

has_extra_len = true;
}
has_extra_len = true;
}

if has_extra_len {
match_len -= 15;

if match_len < 255 {
out_buf.push(match_len as u8);
out_buf.push(match_len as u8);
metadata_size += mem::size_of::<u8>();
} else {
out_buf.push(255);
Expand Down Expand Up @@ -337,4 +326,4 @@ pub fn compress(
store32le!(out_buf, flag_out_off, flags);

Ok(out_buf)
}
}
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ pub enum Error {
CorruptedData,
// An unknown error
Other,
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod error;
pub mod data;
pub mod error;
pub mod lznt1;
Loading