diff --git a/rust/src/detect/transforms/decompress.rs b/rust/src/detect/transforms/decompress.rs index bf5d0aa95c..1e8b9e626f 100644 --- a/rust/src/detect/transforms/decompress.rs +++ b/rust/src/detect/transforms/decompress.rs @@ -20,8 +20,8 @@ use crate::detect::SIGMATCH_OPTIONAL_OPT; use flate2::bufread::{GzDecoder, ZlibDecoder}; use suricata_sys::sys::{ DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister, - SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate, - SCTransformTableElmt, Signature, + SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferInPlace, + SCInspectionBufferTruncate, SCTransformTableElmt, Signature, }; use std::ffi::CStr; @@ -132,26 +132,27 @@ unsafe fn decompress_transform( if input.is_null() || input_len == 0 { return; } - let input = build_slice!(input, input_len as usize); + let tmp; + let slice_input = if SCInspectionBufferInPlace(buffer) { + // need a temporary buffer as we cannot do the transfom in place + // rather copy the input which should be smaller than the decompressed output + // (Transform is tried in place when there are multiple chained transforms) + // needs to happen before possible realloc in SCInspectionBufferCheckAndExpand + tmp = build_slice!(input, input_len as usize).to_vec(); + &tmp + } else { + build_slice!(input, input_len as usize) + }; + let output = SCInspectionBufferCheckAndExpand(buffer, ctx.max_size); if output.is_null() { // allocation failure return; } let buf = std::slice::from_raw_parts_mut(output, ctx.max_size as usize); - let mut tmp = Vec::new(); - let input = if std::ptr::eq(output, input.as_ptr()) { - // need a temporary buffer as we cannot do the transfom in place - // rather copy the input which should be smaller than the decompressed output - // (Transform is tried in place when there are multiple chaines transforms) - tmp.extend_from_slice(input); - &tmp - } else { - input - }; // this succeeds if decompressed data > max_size, but we get nb = max_size - if let Some(nb) = decompress_fn(input, buf) { + if let Some(nb) = decompress_fn(slice_input, buf) { SCInspectionBufferTruncate(buffer, nb); } else { // decompression failure