about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@tvl.su>2024-08-22T13·54+0300
committerclbot <clbot@tvl.fyi>2024-08-22T14·02+0000
commit8f6f45097e36c2cd571ce1b858fdb471697dd7e5 (patch)
tree739ae44664a64cedabc252b75322c62c85c98e74
parent012da7d0e19e272450e3a5ecd91f4f8b97a88c27 (diff)
feat(tazjin/german-string): add constructor that leaks a Vec<u8> r/8551
Change-Id: Id0b6b4794128573ddb62e82fd77d080e564978be
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12264
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
Autosubmit: tazjin <tazjin@tvl.su>
-rw-r--r--users/tazjin/german-string/src/lib.rs31
1 files 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<u8>) -> 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())