From 0dddac7278c8b9cf3c1e4c1c71e620a78ec1c185 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 2 Jan 2026 17:24:00 +0100 Subject: [PATCH] http: do not use recursion in decompression just loop and iterate Ticket: 8185 (cherry picked from commit f2a45c4216388471b0e89eb06a02de27a2fdf901) --- rust/htp/src/decompressors.rs | 76 +++++++++++++++++------------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/rust/htp/src/decompressors.rs b/rust/htp/src/decompressors.rs index c58c4327df..9df5b915e2 100644 --- a/rust/htp/src/decompressors.rs +++ b/rust/htp/src/decompressors.rs @@ -912,45 +912,45 @@ impl Write for InnerDecompressor { // references. Any calls using `self.writer` should be avoided while the // writer is in this state. } else if let Some(mut writer) = self.writer.take() { - match writer.write(data) { - Ok(consumed) => { - let result = if consumed == 0 { - // This could indicate that we have reached the end - // of the stream. Any data after the first end of - // stream (such as in multipart gzip) is ignored and - // we pretend to have consumed this data. - Ok(data.len()) - } else { - Ok(consumed) - }; - self.writer.replace(writer); - result - } - Err(e) => { - match e.kind() { - std::io::ErrorKind::WriteZero => { - self.flush_writer(&mut writer)?; - // Recursion: the buffer was flushed until `WriteZero` - // stopped occuring. - self.writer.replace(writer); - self.write(data) - } - _ => { - if self.restarts == 0 { - let written = self.try_finish(&mut writer); - if written { - // error, but some data has been written, stop here - return Err(e); - } + loop { + match writer.write(data) { + Ok(consumed) => { + let result = if consumed == 0 { + // This could indicate that we have reached the end + // of the stream. Any data after the first end of + // stream (such as in multipart gzip) is ignored and + // we pretend to have consumed this data. + Ok(data.len()) + } else { + Ok(consumed) + }; + self.writer.replace(writer); + return result; + } + Err(e) => { + match e.kind() { + std::io::ErrorKind::WriteZero => { + self.flush_writer(&mut writer)?; + // Recursion: the buffer was flushed until `WriteZero` + // stopped occuring. } - // try to restart, any data in the temp buffer will be - // discarded - if self.restart().is_err() { - self.try_passthrough(data) - } else { - // Recursion: restart will fail after a small - // number of attempts - self.write(data) + _ => { + if self.restarts == 0 { + let written = self.try_finish(&mut writer); + if written { + // error, but some data has been written, stop here + return Err(e); + } + } + // try to restart, any data in the temp buffer will be + // discarded + if self.restart().is_err() { + return self.try_passthrough(data); + } else { + // Recursion: restart will fail after a small + // number of attempts + return self.write(data); + } } } }