From a4ac5dea70357c90178342493c681d5dcad0feeb Mon Sep 17 00:00:00 2001 From: Chris Hennick Date: Sun, 2 Jul 2023 08:53:44 -0700 Subject: [PATCH] Fix stack overflow by building HashThing and ZopfliHash on heap --- src/hash.rs | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/hash.rs b/src/hash.rs index 482f4d6..93732b1 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -1,3 +1,4 @@ +use std::alloc::{alloc, Layout}; use once_cell::sync::Lazy; use crate::util::{ZOPFLI_MIN_MATCH, ZOPFLI_WINDOW_MASK, ZOPFLI_WINDOW_SIZE}; @@ -24,25 +25,24 @@ pub struct HashThing { val: u16, /* Current hash value. */ } -const EMPTY_HASH_THING: Lazy = Lazy::new(|| { +const EMPTY_HASH_THING: Lazy> = Lazy::new(|| { let mut prev_and_hashval = [SmallerHashThing { prev: 0, hashval: None }; ZOPFLI_WINDOW_SIZE]; for i in 0..(ZOPFLI_WINDOW_SIZE as u16) { prev_and_hashval[i as usize].prev = i; } - HashThing { - head: [-1; 65536], - prev_and_hashval, - val: 0, + unsafe { + let layout = Layout::new::(); + let ptr = alloc(layout) as *mut HashThing; + (*ptr).head = [-1; 65536]; + (*ptr).prev_and_hashval = prev_and_hashval; + (*ptr).val = 0; + Box::from_raw(ptr) } }); impl HashThing { - fn new() -> HashThing { - EMPTY_HASH_THING.clone() - } - fn reset(&mut self) { self.val = 0; @@ -88,11 +88,14 @@ pub struct ZopfliHash { } impl ZopfliHash { - pub fn new() -> ZopfliHash { - ZopfliHash { - hash1: HashThing::new(), - hash2: HashThing::new(), - same: [0; ZOPFLI_WINDOW_SIZE], + pub fn new() -> Box { + unsafe { + let layout = Layout::new::(); + let ptr = alloc(layout) as *mut ZopfliHash; + (*ptr).hash1 = **EMPTY_HASH_THING; + (*ptr).hash2 = **EMPTY_HASH_THING; + (*ptr).same = [0; ZOPFLI_WINDOW_SIZE]; + Box::from_raw(ptr) } }