From 283a666bff39dcc1d630c131d997e2c2337071f1 Mon Sep 17 00:00:00 2001 From: Danny Kim Date: Sat, 26 Sep 2026 05:06:54 +0900 Subject: [PATCH] A file read back at the signing limit can still be saved --- src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index c3b3fb6..051e887 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,9 @@ const MAX_CHUNK: u32 = 1024 * 1024; /// plus 110 per byte, so a larger file would run out mid-call and leave the /// save's outcome unknown. It is refused up front instead. const MAX_SIGNED: usize = 96 * 1024; +/// Room a save may carry beyond [`MAX_SIGNED`] before its verdict line is +/// dropped, so a file read back at the limit can be saved unedited. +const BADGE_ALLOWANCE: usize = 4 * 1024; /// The largest Markdown file a read decorates with a verdict line. Memona /// opens files of at most one transfer, and a larger one streams through. const MAX_DECORATED: usize = MAX_CHUNK as usize; @@ -270,7 +273,7 @@ impl GuestWriter for DavWriter { return self.send(&data); }; let mut markdown = markdown.borrow_mut(); - if markdown.len() + data.len() > MAX_SIGNED { + if markdown.len() + data.len() > MAX_SIGNED + BADGE_ALLOWANCE { return Err(ErrorCode::Unsupported); } markdown.extend_from_slice(&data); @@ -291,6 +294,9 @@ impl GuestWriter for DavWriter { let text = std::str::from_utf8(&markdown).map_err(|_| ErrorCode::InvalidInput)?; let stored = badge::strip(text); + if stored.len() > MAX_SIGNED { + return Err(ErrorCode::Unsupported); + } let signed = session(|session| session.signer.sign(stored.as_bytes()))?; for piece in signed.chunks(MAX_CHUNK as usize) { self.send(piece)?;