diff --git a/src/stream/source.rs b/src/stream/source.rs index 33a1ac7..83895a0 100644 --- a/src/stream/source.rs +++ b/src/stream/source.rs @@ -195,7 +195,7 @@ where R: Read { #[cfg(feature="explicit_clear")] { - bytes::explicit_prune(K::buffer_bytes_mut(self)); + bytes::explicit_prune(K::buffer_bytes_mut(&mut self.buffer)); return; } #[cfg(not(feature="explicit_clear"))] @@ -232,20 +232,37 @@ impl Source } } +fn try_alloca(sz: usize, cb: impl FnOnce(&mut [u8]) -> T) -> T +{ + if sz > STACK_MAX_BYTES { + let mut bytes = vec![0u8; sz]; + cb(&mut bytes[..]) + } else { + stackalloc::alloca_zeroed(sz, cb) + } +} + impl Read for Source where R: Read { fn read(&mut self, buf: &mut [u8]) -> io::Result { if cfg!(feature="reuse-buffer") { //XXX: FUck, we can't `crypter.update()` in place.... - let read = self.stream.read(buf)?; - todo!() - + + try_alloca(buf.len(), move |temp| -> io::Result { + let read = self.stream.read(temp)?; + let b = self.transform_into(&temp[..read], &mut buf[..read])?; + #[cfg(feature="explicit_clear")] bytes::explicit_prune(&mut temp[..b]); + Ok(b) + }) } else { self.grow_to_fit(buf.len()); let read = self.stream.read(&mut K::buffer_bytes_mut(&mut self.buffer)[..buf.len()])?; - Ok(self.transform(read, &mut buf[..read])?) + let b = self.transform(read, &mut buf[..read])?; + + #[cfg(feature="explicit_clear")] bytes::explicit_prune(&mut K::buffer_bytes_mut(&mut self.buffer)[..b]); + Ok(b) } } }