Skip to content

Commit 1cb0a25

Browse files
committed
fix: do not ignore I/O errors in BlobObject::store_from_base64
1 parent fdea6c8 commit 1cb0a25

File tree

4 files changed

+28
-24
lines changed

4 files changed

+28
-24
lines changed

src/blob.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,13 @@ impl<'a> BlobObject<'a> {
234234
/// If `data` represents an image of known format, this adds the corresponding extension.
235235
///
236236
/// Even though this function is not async, it's OK to call it from an async context.
237-
pub(crate) fn store_from_base64(context: &Context, data: &str) -> Result<String> {
238-
let buf = base64::engine::general_purpose::STANDARD.decode(data)?;
237+
///
238+
/// Returns an error if there is an I/O problem,
239+
/// but in case of a failure to decode base64 returns `Ok(None)`.
240+
pub(crate) fn store_from_base64(context: &Context, data: &str) -> Result<Option<String>> {
241+
let Ok(buf) = base64::engine::general_purpose::STANDARD.decode(data) else {
242+
return Ok(None);
243+
};
239244
let name = if let Ok(format) = image::guess_format(&buf) {
240245
if let Some(ext) = format.extensions_str().first() {
241246
format!("file.{ext}")
@@ -246,7 +251,7 @@ impl<'a> BlobObject<'a> {
246251
String::new()
247252
};
248253
let blob = BlobObject::create_and_deduplicate_from_bytes(context, &buf, &name)?;
249-
Ok(blob.as_name().to_string())
254+
Ok(Some(blob.as_name().to_string()))
250255
}
251256

252257
/// Recode image to avatar size.

src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ impl Context {
665665
Config::Selfavatar if value.is_empty() => None,
666666
Config::Selfavatar => {
667667
config_value = BlobObject::store_from_base64(self, value)?;
668-
Some(config_value.as_str())
668+
config_value.as_deref()
669669
}
670670
_ => Some(value),
671671
};

src/contact.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -369,16 +369,15 @@ async fn import_vcard_contact(context: &Context, contact: &VcardContact) -> Resu
369369
return Ok(id);
370370
}
371371
let path = match &contact.profile_image {
372-
Some(image) => match BlobObject::store_from_base64(context, image) {
373-
Err(e) => {
372+
Some(image) => match BlobObject::store_from_base64(context, image)? {
373+
None => {
374374
warn!(
375375
context,
376-
"import_vcard_contact: Could not decode and save avatar for {}: {e:#}.",
377-
contact.addr
376+
"import_vcard_contact: Could not decode avatar for {}.", contact.addr
378377
);
379378
None
380379
}
381-
Ok(path) => Some(path),
380+
Some(path) => Some(path),
382381
},
383382
None => None,
384383
};

src/mimeparser.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -714,14 +714,16 @@ impl MimeMessage {
714714
}
715715

716716
/// Parses avatar action headers.
717-
fn parse_avatar_headers(&mut self, context: &Context) {
717+
fn parse_avatar_headers(&mut self, context: &Context) -> Result<()> {
718718
if let Some(header_value) = self.get_header(HeaderDef::ChatGroupAvatar) {
719-
self.group_avatar = self.avatar_action_from_header(context, header_value.to_string());
719+
self.group_avatar =
720+
self.avatar_action_from_header(context, header_value.to_string())?;
720721
}
721722

722723
if let Some(header_value) = self.get_header(HeaderDef::ChatUserAvatar) {
723-
self.user_avatar = self.avatar_action_from_header(context, header_value.to_string());
724+
self.user_avatar = self.avatar_action_from_header(context, header_value.to_string())?;
724725
}
726+
Ok(())
725727
}
726728

727729
fn parse_videochat_headers(&mut self) {
@@ -828,7 +830,7 @@ impl MimeMessage {
828830

829831
async fn parse_headers(&mut self, context: &Context) -> Result<()> {
830832
self.parse_system_message_headers(context);
831-
self.parse_avatar_headers(context);
833+
self.parse_avatar_headers(context)?;
832834
self.parse_videochat_headers();
833835
if self.delivery_report.is_none() {
834836
self.squash_attachment_parts();
@@ -930,21 +932,18 @@ impl MimeMessage {
930932
&mut self,
931933
context: &Context,
932934
header_value: String,
933-
) -> Option<AvatarAction> {
934-
if header_value == "0" {
935+
) -> Result<Option<AvatarAction>> {
936+
let res = if header_value == "0" {
935937
Some(AvatarAction::Delete)
936938
} else if let Some(base64) = header_value
937939
.split_ascii_whitespace()
938940
.collect::<String>()
939941
.strip_prefix("base64:")
940942
{
941-
match BlobObject::store_from_base64(context, base64) {
942-
Ok(path) => Some(AvatarAction::Change(path)),
943-
Err(err) => {
944-
warn!(
945-
context,
946-
"Could not decode and save avatar to blob file: {:#}", err,
947-
);
943+
match BlobObject::store_from_base64(context, base64)? {
944+
Some(path) => Some(AvatarAction::Change(path)),
945+
None => {
946+
warn!(context, "Could not decode avatar base64");
948947
None
949948
}
950949
}
@@ -958,15 +957,16 @@ impl MimeMessage {
958957
if let Some(blob) = part.param.get(Param::File) {
959958
let res = Some(AvatarAction::Change(blob.to_string()));
960959
self.parts.remove(i);
961-
return res;
960+
return Ok(res);
962961
}
963962
break;
964963
}
965964
}
966965
i += 1;
967966
}
968967
None
969-
}
968+
};
969+
Ok(res)
970970
}
971971

972972
/// Returns true if the message was encrypted as defined in

0 commit comments

Comments
 (0)