mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-16 15:21:24 +01:00
rewrite media key parser
Fixes a regression ine2cba15ed2where the Content-Type and Content-Disposition parts are extracted in the wrong order. Fixes a long-standing issue inb6d721374fwhere the Content-Type part was allowed to be completely missing rather than present and 0 bytes long. Improves the error messages for various parsing failures to be unique and more obvious.
This commit is contained in:
parent
88b009a8d4
commit
d388994657
1 changed files with 44 additions and 34 deletions
|
|
@ -26,57 +26,67 @@ impl TryFrom<&MediaFileKey> for MediaFileKeyParts {
|
|||
fn try_from(key: &MediaFileKey) -> Result<MediaFileKeyParts> {
|
||||
let mut parts = key.as_bytes().split(|&b| b == 0xFF);
|
||||
|
||||
// Extract parts
|
||||
|
||||
let mxc_bytes = parts
|
||||
.next()
|
||||
.ok_or_else(|| Error::BadDatabase("Media ID in db is invalid."))?;
|
||||
.ok_or_else(|| Error::BadDatabase("Missing MXC URI bytes"))?;
|
||||
|
||||
let thumbnail_size_bytes = parts.next().ok_or_else(|| {
|
||||
Error::BadDatabase("Missing thumbnail size bytes")
|
||||
})?;
|
||||
|
||||
let content_disposition_bytes = parts.next().ok_or_else(|| {
|
||||
Error::BadDatabase("Missing Content-Disposition bytes")
|
||||
})?;
|
||||
|
||||
let content_type_bytes = parts
|
||||
.next()
|
||||
.ok_or_else(|| Error::BadDatabase("Missing Content-Type bytes"))?;
|
||||
|
||||
if parts.next().is_some() {
|
||||
return Err(Error::BadDatabase("Too many parts"));
|
||||
}
|
||||
|
||||
// Parse parts
|
||||
|
||||
let mxc = utils::string_from_bytes(mxc_bytes)
|
||||
.map_err(|_| {
|
||||
Error::BadDatabase("Media MXC URI in db is invalid unicode.")
|
||||
})?
|
||||
.map_err(|_| Error::BadDatabase("Invalid unicode in MXC URI"))?
|
||||
.into();
|
||||
|
||||
let thumbnail_size_bytes = parts
|
||||
.next()
|
||||
.ok_or_else(|| Error::BadDatabase("Media ID in db is invalid."))?;
|
||||
let thumbnail_size_bytes: &[u8; 8] =
|
||||
thumbnail_size_bytes.try_into().map_err(|_| {
|
||||
Error::BadDatabase("Media ID thumbnail size in db is invalid")
|
||||
})?;
|
||||
let width = u32::from_be_bytes(
|
||||
thumbnail_size_bytes[..4].try_into().expect("should be 4 bytes"),
|
||||
);
|
||||
let height = u32::from_be_bytes(
|
||||
thumbnail_size_bytes[4..].try_into().expect("should be 4 bytes"),
|
||||
);
|
||||
let (width, height) = <&[u8; 8]>::try_from(thumbnail_size_bytes)
|
||||
.map(|eight_bytes| {
|
||||
let width = u32::from_be_bytes(
|
||||
eight_bytes[..4].try_into().expect("should be 4 bytes"),
|
||||
);
|
||||
let height = u32::from_be_bytes(
|
||||
eight_bytes[4..].try_into().expect("should be 4 bytes"),
|
||||
);
|
||||
|
||||
let content_type = parts
|
||||
.next()
|
||||
.map(|bytes| {
|
||||
utils::string_from_bytes(bytes).map_err(|_| {
|
||||
Error::BadDatabase(
|
||||
"Content type in mediaid_file is invalid unicode.",
|
||||
)
|
||||
})
|
||||
(width, height)
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let content_disposition_bytes = parts
|
||||
.next()
|
||||
.ok_or_else(|| Error::BadDatabase("Media ID in db is invalid."))?;
|
||||
.map_err(|_| {
|
||||
Error::BadDatabase("Wrong number of thumbnail size bytes")
|
||||
})?;
|
||||
|
||||
let content_disposition = if content_disposition_bytes.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(utils::string_from_bytes(content_disposition_bytes).map_err(
|
||||
|_| {
|
||||
Error::BadDatabase(
|
||||
"Content Disposition in mediaid_file is invalid \
|
||||
unicode.",
|
||||
)
|
||||
Error::BadDatabase("Invalid unicode in Content-Disposition")
|
||||
},
|
||||
)?)
|
||||
};
|
||||
|
||||
let content_type = if content_type_bytes.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(utils::string_from_bytes(content_type_bytes).map_err(
|
||||
|_| Error::BadDatabase("Invalid unicode in Content-Type"),
|
||||
)?)
|
||||
};
|
||||
|
||||
Ok(MediaFileKeyParts {
|
||||
mxc,
|
||||
width,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue