From 8f6f45097e36c2cd571ce1b858fdb471697dd7e5 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Thu, 22 Aug 2024 16:54:14 +0300 Subject: feat(tazjin/german-string): add constructor that leaks a Vec Change-Id: Id0b6b4794128573ddb62e82fd77d080e564978be Reviewed-on: https://cl.tvl.fyi/c/depot/+/12264 Tested-by: BuildkiteCI Reviewed-by: tazjin Autosubmit: tazjin --- users/tazjin/german-string/src/lib.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/users/tazjin/german-string/src/lib.rs b/users/tazjin/german-string/src/lib.rs index 05e43ed103ad..5cc8aebaab96 100644 --- a/users/tazjin/german-string/src/lib.rs +++ b/users/tazjin/german-string/src/lib.rs @@ -122,11 +122,11 @@ impl GermanString { s.data[..bytes.len()].copy_from_slice(&bytes); GermanString(GSRepr { small: s }) } else { - let mut md = std::mem::ManuallyDrop::new(bytes); + let md = std::mem::ManuallyDrop::new(bytes); let mut large = GSLarge { len: md.len() as u32, prefix: [0u8; 4], - data: StorageClassPtr::transient(md.as_mut_ptr()), + data: StorageClassPtr::transient(md.as_ptr()), }; large.prefix.copy_from_slice(&md[..4]); @@ -160,6 +160,33 @@ impl GermanString { } } + /// Creates a persistent German String by leaking the provided data. + pub fn persistent_leak(bytes: Vec) -> GermanString { + if bytes.len() > u32::MAX as usize { + panic!("GermanString maximum length is {} bytes", u32::MAX); + } + + if bytes.len() <= 12 { + let mut s = GSSmall { + len: bytes.len() as u32, + data: [0u8; 12], + }; + + s.data[..bytes.len()].copy_from_slice(&bytes); + GermanString(GSRepr { small: s }) + } else { + let md = std::mem::ManuallyDrop::new(bytes); + let mut large = GSLarge { + len: md.len() as u32, + prefix: [0u8; 4], + data: StorageClassPtr::persistent(md.as_ptr()), + }; + + large.prefix.copy_from_slice(&md[..4]); + GermanString(GSRepr { large }) + } + } + /// Creates a persistent German String from a static data buffer. pub fn persistent_from_str(s: &'static str) -> GermanString { GermanString::persistent(s.as_bytes()) -- cgit 1.4.1