diff --git a/src/database/key_value/media.rs b/src/database/key_value/media.rs index 9fc15e54..713c8b05 100644 --- a/src/database/key_value/media.rs +++ b/src/database/key_value/media.rs @@ -24,18 +24,37 @@ impl TryFrom<&MediaFileKey> for MediaFileKeyParts { fields(key = utils::u8_slice_to_hex(key.as_bytes())), )] fn try_from(key: &MediaFileKey) -> Result { - let mut parts = key.as_bytes().split(|&b| b == 0xFF); - // Extract parts + // Extracting mxc url and thumbnail size is a bit fiddly, because the + // thumbnail size may contain 0xFF bytes. + let mut parts = key.as_bytes().splitn(2, |&b| b == 0xFF); + let mxc_bytes = parts .next() .ok_or_else(|| Error::BadDatabase("Missing MXC URI bytes"))?; - let thumbnail_size_bytes = parts.next().ok_or_else(|| { + let rest = parts.next().ok_or_else(|| { Error::BadDatabase("Missing thumbnail size bytes") })?; + // Thumbnail size is always 8 bytes + let (thumbnail_size_bytes, rest) = + rest.split_at_checked(8).ok_or_else(|| { + Error::BadDatabase("Missing thumbnail size bytes") + })?; + + // And always followed immediately by a 0xFF separator + let mut parts = rest.split(|&b| b == 0xFF); + + let thumbnail_size_rest = parts.next().ok_or_else(|| { + Error::BadDatabase("Missing Content-Disposition bytes") + })?; + if !thumbnail_size_rest.is_empty() { + return Err(Error::BadDatabase("Thumbnail size part is too long")); + } + + // The remaining parts are straightforward 0xFF-delimited fields let content_disposition_bytes = parts.next().ok_or_else(|| { Error::BadDatabase("Missing Content-Disposition bytes") })?;