From 3fcd17e6a5bce0101a65a97160440c4b004209a8 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 27 Dec 2022 12:02:23 +0000 Subject: [PATCH 01/39] Add missing documentation for Summary constructor --- src/summary.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/summary.rs b/src/summary.rs index cbf301ed7..5b4d3f0bc 100644 --- a/src/summary.rs +++ b/src/summary.rs @@ -1,7 +1,5 @@ //! # Message summary for chatlist. -#![allow(missing_docs)] - use crate::chat::Chat; use crate::constants::Chattype; use crate::contact::{Contact, ContactId}; @@ -54,6 +52,8 @@ pub struct Summary { } impl Summary { + /// Constucts chatlist summary + /// from the provided message, chat and message author contact snapshots. pub async fn new( context: &Context, msg: &Message, From 5432e108a1cdeb3d15eade329238f986e71c2e83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Dec 2022 15:16:12 +0000 Subject: [PATCH 02/39] cargo: bump quick-xml from 0.23.0 to 0.26.0 Bumps [quick-xml](https://github.com/tafia/quick-xml) from 0.23.0 to 0.26.0. - [Release notes](https://github.com/tafia/quick-xml/releases) - [Changelog](https://github.com/tafia/quick-xml/blob/master/Changelog.md) - [Commits](https://github.com/tafia/quick-xml/compare/v0.23.0...v0.26.0) --- updated-dependencies: - dependency-name: quick-xml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- CHANGELOG.md | 1 + Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/configure/auto_mozilla.rs | 31 +++++++++++++++----------- src/configure/auto_outlook.rs | 24 +++++++++++++------- src/dehtml.rs | 39 +++++++++++++++++++++++++-------- src/location.rs | 41 +++++++++++++++++++++++------------ 7 files changed, 95 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8edd9f065..9db270c67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Validate signatures in try_decrypt() even if the message isn't encrypted #3859 - Don't parse the message again after detached signatures validation #3862 - Move format=flowed support to a separate crate #3869 +- cargo: bump quick-xml from 0.23.0 to 0.26.0 #3722 ### API-Changes - jsonrpc: add python API for webxdc updates #3872 diff --git a/Cargo.lock b/Cargo.lock index 198ae37eb..33f9f9eda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2739,9 +2739,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.23.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9279fbdacaad3baf559d8cabe0acc3d06e30ea14931af31af79578ac0946decc" +checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 9fbd387e3..a76e6d5c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ once_cell = "1.16.0" percent-encoding = "2.2" pgp = { version = "0.9", default-features = false } pretty_env_logger = { version = "0.4", optional = true } -quick-xml = "0.23" +quick-xml = "0.26" r2d2 = "0.8" r2d2_sqlite = "0.20" rand = "0.8" diff --git a/src/configure/auto_mozilla.rs b/src/configure/auto_mozilla.rs index bc7b69712..2f5ca45b2 100644 --- a/src/configure/auto_mozilla.rs +++ b/src/configure/auto_mozilla.rs @@ -62,7 +62,7 @@ fn parse_server( reader: &mut quick_xml::Reader, server_event: &BytesStart, ) -> Result, quick_xml::Error> { - let end_tag = String::from_utf8_lossy(server_event.name()) + let end_tag = String::from_utf8_lossy(server_event.name().as_ref()) .trim() .to_lowercase(); @@ -70,12 +70,17 @@ fn parse_server( .attributes() .find(|attr| { attr.as_ref() - .map(|a| String::from_utf8_lossy(a.key).trim().to_lowercase() == "type") + .map(|a| { + String::from_utf8_lossy(a.key.as_ref()) + .trim() + .to_lowercase() + == "type" + }) .unwrap_or_default() }) .map(|typ| { typ.unwrap() - .unescape_and_decode_value(reader) + .decode_and_unescape_value(reader) .unwrap_or_default() .to_lowercase() }) @@ -89,25 +94,23 @@ fn parse_server( let mut tag_config = MozConfigTag::Undefined; let mut buf = Vec::new(); loop { - match reader.read_event(&mut buf)? { + match reader.read_event_into(&mut buf)? { Event::Start(ref event) => { - tag_config = String::from_utf8_lossy(event.name()) + tag_config = String::from_utf8_lossy(event.name().as_ref()) .parse() .unwrap_or_default(); } Event::End(ref event) => { - let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); + let tag = String::from_utf8_lossy(event.name().as_ref()) + .trim() + .to_lowercase(); if tag == end_tag { break; } } Event::Text(ref event) => { - let val = event - .unescape_and_decode(reader) - .unwrap_or_default() - .trim() - .to_owned(); + let val = event.unescape().unwrap_or_default().trim().to_owned(); match tag_config { MozConfigTag::Hostname => hostname = Some(val), @@ -150,9 +153,11 @@ fn parse_xml_reader( let mut buf = Vec::new(); loop { - match reader.read_event(&mut buf)? { + match reader.read_event_into(&mut buf)? { Event::Start(ref event) => { - let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); + let tag = String::from_utf8_lossy(event.name().as_ref()) + .trim() + .to_lowercase(); if tag == "incomingserver" { if let Some(incoming_server) = parse_server(reader, event)? { diff --git a/src/configure/auto_outlook.rs b/src/configure/auto_outlook.rs index 0be2f520a..d374f7016 100644 --- a/src/configure/auto_outlook.rs +++ b/src/configure/auto_outlook.rs @@ -59,12 +59,18 @@ fn parse_protocol( let mut current_tag: Option = None; loop { - match reader.read_event(&mut buf)? { + match reader.read_event_into(&mut buf)? { Event::Start(ref event) => { - current_tag = Some(String::from_utf8_lossy(event.name()).trim().to_lowercase()); + current_tag = Some( + String::from_utf8_lossy(event.name().as_ref()) + .trim() + .to_lowercase(), + ); } Event::End(ref event) => { - let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); + let tag = String::from_utf8_lossy(event.name().as_ref()) + .trim() + .to_lowercase(); if tag == "protocol" { break; } @@ -73,7 +79,7 @@ fn parse_protocol( } } Event::Text(ref e) => { - let val = e.unescape_and_decode(reader).unwrap_or_default(); + let val = e.unescape().unwrap_or_default(); if let Some(ref tag) = current_tag { match tag.as_str() { @@ -115,9 +121,9 @@ fn parse_redirecturl( reader: &mut quick_xml::Reader, ) -> Result { let mut buf = Vec::new(); - match reader.read_event(&mut buf)? { + match reader.read_event_into(&mut buf)? { Event::Text(ref e) => { - let val = e.unescape_and_decode(reader).unwrap_or_default(); + let val = e.unescape().unwrap_or_default(); Ok(val.trim().to_string()) } _ => Ok("".to_string()), @@ -131,9 +137,11 @@ fn parse_xml_reader( let mut buf = Vec::new(); loop { - match reader.read_event(&mut buf)? { + match reader.read_event_into(&mut buf)? { Event::Start(ref e) => { - let tag = String::from_utf8_lossy(e.name()).trim().to_lowercase(); + let tag = String::from_utf8_lossy(e.name().as_ref()) + .trim() + .to_lowercase(); if tag == "protocol" { if let Some(protocol) = parse_protocol(reader)? { diff --git a/src/dehtml.rs b/src/dehtml.rs index 20075dbab..30c96e366 100644 --- a/src/dehtml.rs +++ b/src/dehtml.rs @@ -88,18 +88,30 @@ fn dehtml_quick_xml(buf: &str) -> String { let mut buf = Vec::new(); loop { - match reader.read_event(&mut buf) { + match reader.read_event_into(&mut buf) { Ok(quick_xml::events::Event::Start(ref e)) => { dehtml_starttag_cb(e, &mut dehtml, &reader) } Ok(quick_xml::events::Event::End(ref e)) => dehtml_endtag_cb(e, &mut dehtml), Ok(quick_xml::events::Event::Text(ref e)) => dehtml_text_cb(e, &mut dehtml), - Ok(quick_xml::events::Event::CData(e)) => dehtml_text_cb(&e.escape(), &mut dehtml), + Ok(quick_xml::events::Event::CData(e)) => match e.escape() { + Ok(e) => dehtml_text_cb(&e, &mut dehtml), + Err(e) => { + eprintln!( + "CDATA escape error at position {}: {:?}", + reader.buffer_position(), + e, + ); + } + }, Ok(quick_xml::events::Event::Empty(ref e)) => { // Handle empty tags as a start tag immediately followed by end tag. // For example, `

` is treated as `

`. dehtml_starttag_cb(e, &mut dehtml, &reader); - dehtml_endtag_cb(&BytesEnd::borrowed(e.name()), &mut dehtml); + dehtml_endtag_cb( + &BytesEnd::new(String::from_utf8_lossy(e.name().as_ref())), + &mut dehtml, + ); } Err(e) => { eprintln!( @@ -121,7 +133,7 @@ fn dehtml_text_cb(event: &BytesText, dehtml: &mut Dehtml) { if dehtml.get_add_text() == AddText::YesPreserveLineEnds || dehtml.get_add_text() == AddText::YesRemoveLineEnds { - let last_added = escaper::decode_html_buf_sloppy(event.escaped()).unwrap_or_default(); + let last_added = escaper::decode_html_buf_sloppy(event as &[_]).unwrap_or_default(); if dehtml.get_add_text() == AddText::YesRemoveLineEnds { dehtml.strbuilder += LINE_RE.replace_all(&last_added, "\r").as_ref(); @@ -135,7 +147,9 @@ fn dehtml_text_cb(event: &BytesText, dehtml: &mut Dehtml) { } fn dehtml_endtag_cb(event: &BytesEnd, dehtml: &mut Dehtml) { - let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); + let tag = String::from_utf8_lossy(event.name().as_ref()) + .trim() + .to_lowercase(); match tag.as_str() { "p" | "table" | "td" | "style" | "script" | "title" | "pre" => { @@ -176,7 +190,9 @@ fn dehtml_starttag_cb( dehtml: &mut Dehtml, reader: &quick_xml::Reader, ) { - let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); + let tag = String::from_utf8_lossy(event.name().as_ref()) + .trim() + .to_lowercase(); match tag.as_str() { "p" | "table" | "td" => { @@ -206,10 +222,15 @@ fn dehtml_starttag_cb( if let Some(href) = event .html_attributes() .filter_map(|attr| attr.ok()) - .find(|attr| String::from_utf8_lossy(attr.key).trim().to_lowercase() == "href") + .find(|attr| { + String::from_utf8_lossy(attr.key.as_ref()) + .trim() + .to_lowercase() + == "href" + }) { let href = href - .unescape_and_decode_value(reader) + .decode_and_unescape_value(reader) .unwrap_or_default() .to_lowercase(); @@ -258,7 +279,7 @@ fn maybe_push_tag( fn tag_contains_attr(event: &BytesStart, reader: &Reader, name: &str) -> bool { event.attributes().any(|r| { r.map(|a| { - a.unescape_and_decode_value(reader) + a.decode_and_unescape_value(reader) .map(|v| v == name) .unwrap_or(false) }) diff --git a/src/location.rs b/src/location.rs index e381039ac..8467d4aaf 100644 --- a/src/location.rs +++ b/src/location.rs @@ -78,7 +78,7 @@ impl Kml { let mut buf = Vec::new(); loop { - match reader.read_event(&mut buf).with_context(|| { + match reader.read_event_into(&mut buf).with_context(|| { format!( "location parsing error at position {}", reader.buffer_position() @@ -86,7 +86,7 @@ impl Kml { })? { quick_xml::events::Event::Start(ref e) => kml.starttag_cb(e, &reader), quick_xml::events::Event::End(ref e) => kml.endtag_cb(e), - quick_xml::events::Event::Text(ref e) => kml.text_cb(e, &reader), + quick_xml::events::Event::Text(ref e) => kml.text_cb(e), quick_xml::events::Event::Eof => break, _ => (), } @@ -96,9 +96,9 @@ impl Kml { Ok(kml) } - fn text_cb(&mut self, event: &BytesText, reader: &quick_xml::Reader) { + fn text_cb(&mut self, event: &BytesText) { if self.tag.contains(KmlTag::WHEN) || self.tag.contains(KmlTag::COORDINATES) { - let val = event.unescape_and_decode(reader).unwrap_or_default(); + let val = event.unescape().unwrap_or_default(); let val = val.replace(['\n', '\r', '\t', ' '], ""); @@ -127,7 +127,9 @@ impl Kml { } fn endtag_cb(&mut self, event: &BytesEnd) { - let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); + let tag = String::from_utf8_lossy(event.name().as_ref()) + .trim() + .to_lowercase(); if tag == "placemark" { if self.tag.contains(KmlTag::PLACEMARK) @@ -147,14 +149,20 @@ impl Kml { event: &BytesStart, reader: &quick_xml::Reader, ) { - let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); + let tag = String::from_utf8_lossy(event.name().as_ref()) + .trim() + .to_lowercase(); if tag == "document" { - if let Some(addr) = event - .attributes() - .filter_map(|a| a.ok()) - .find(|attr| String::from_utf8_lossy(attr.key).trim().to_lowercase() == "addr") - { - self.addr = addr.unescape_and_decode_value(reader).ok(); + if let Some(addr) = event.attributes().filter_map(|a| a.ok()).find(|attr| { + String::from_utf8_lossy(attr.key.as_ref()) + .trim() + .to_lowercase() + == "addr" + }) { + self.addr = addr + .decode_and_unescape_value(reader) + .ok() + .map(|a| a.into_owned()); } } else if tag == "placemark" { self.tag = KmlTag::PLACEMARK; @@ -172,12 +180,17 @@ impl Kml { self.tag = KmlTag::PLACEMARK | KmlTag::POINT | KmlTag::COORDINATES; if let Some(acc) = event.attributes().find(|attr| { attr.as_ref() - .map(|a| String::from_utf8_lossy(a.key).trim().to_lowercase() == "accuracy") + .map(|a| { + String::from_utf8_lossy(a.key.as_ref()) + .trim() + .to_lowercase() + == "accuracy" + }) .unwrap_or_default() }) { let v = acc .unwrap() - .unescape_and_decode_value(reader) + .decode_and_unescape_value(reader) .unwrap_or_default(); self.curr.accuracy = v.trim().parse().unwrap_or_default(); From 6e63555bc8aec62e55b39dedf9258d562afe71ac Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 27 Dec 2022 11:58:01 +0000 Subject: [PATCH 03/39] Add missing documentation for the download state --- src/download.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/download.rs b/src/download.rs index 3253e54fe..de127c7ae 100644 --- a/src/download.rs +++ b/src/download.rs @@ -1,7 +1,5 @@ //! # Download large messages manually. -#![allow(missing_docs)] - use anyhow::{anyhow, Result}; use deltachat_derive::{FromSql, ToSql}; use serde::{Deserialize, Serialize}; @@ -33,6 +31,7 @@ const MIN_DOWNLOAD_LIMIT: u32 = 32768; /// `MIN_DELETE_SERVER_AFTER` increases the timeout in this case. pub(crate) const MIN_DELETE_SERVER_AFTER: i64 = 48 * 60 * 60; +/// Download state of the message. #[derive( Debug, Display, @@ -49,9 +48,16 @@ pub(crate) const MIN_DELETE_SERVER_AFTER: i64 = 48 * 60 * 60; )] #[repr(u32)] pub enum DownloadState { + /// Message is fully downloaded. Done = 0, + + /// Message is partially downloaded and can be fully downloaded at request. Available = 10, + + /// Failed to fully download the message. Failure = 20, + + /// Full download of the message is in progress. InProgress = 1000, } From 256ef7c5ece94bac0157567d32dad665e7e924da Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 27 Dec 2022 11:43:03 +0000 Subject: [PATCH 04/39] Add missing documentation for location streaming --- src/location.rs | 43 ++++++++++++++++++++++++++++++++++++++++--- src/mimefactory.rs | 2 ++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/location.rs b/src/location.rs index e381039ac..9e83ebd7b 100644 --- a/src/location.rs +++ b/src/location.rs @@ -1,7 +1,5 @@ //! Location handling. -#![allow(missing_docs)] - use std::convert::TryFrom; use std::time::Duration; @@ -20,32 +18,63 @@ use crate::mimeparser::SystemMessage; use crate::stock_str; use crate::tools::{duration_to_str, time}; -/// Location record +/// Location record. #[derive(Debug, Clone, Default)] pub struct Location { + /// Row ID of the location. pub location_id: u32, + + /// Location latitude. pub latitude: f64, + + /// Location longitude. pub longitude: f64, + + /// Nonstandard `accuracy` attribute of the `coordinates` tag. pub accuracy: f64, + + /// Location timestamp in seconds. pub timestamp: i64, + + /// Contact ID. pub contact_id: ContactId, + + /// Message ID. pub msg_id: u32, + + /// Chat ID. pub chat_id: ChatId, + + /// A marker string, such as an emoji, to be displayed on top of the location. pub marker: Option, + + /// Whether location is independent, i.e. not part of the path. pub independent: u32, } impl Location { + /// Creates a new empty location. pub fn new() -> Self { Default::default() } } +/// KML document. +/// +/// See for the standard and +/// for documentation. #[derive(Debug, Clone, Default)] pub struct Kml { + /// Nonstandard `addr` attribute of the `Document` tag storing the user email address. pub addr: Option, + + /// Placemarks. pub locations: Vec, + + /// Currently parsed XML tag. tag: KmlTag, + + /// Currently parsed placemark. pub curr: Location, } @@ -62,10 +91,12 @@ bitflags! { } impl Kml { + /// Creates a new empty KML document. pub fn new() -> Self { Default::default() } + /// Parses a KML document. pub fn parse(to_parse: &[u8]) -> Result { ensure!(to_parse.len() <= 1024 * 1024, "kml-file is too large"); @@ -259,6 +290,7 @@ pub async fn is_sending_locations_to_chat( Ok(exists) } +/// Sets current location of the user device. pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64) -> bool { if latitude == 0.0 && longitude == 0.0 { return true; @@ -306,6 +338,7 @@ pub async fn set(context: &Context, latitude: f64, longitude: f64, accuracy: f64 continue_streaming } +/// Searches for locations in the given time range, optionally filtering by chat and contact IDs. pub async fn get_range( context: &Context, chat_id: Option, @@ -396,6 +429,7 @@ pub async fn delete_all(context: &Context) -> Result<()> { Ok(()) } +/// Returns `location.kml` contents. pub async fn get_kml(context: &Context, chat_id: ChatId) -> Result<(String, u32)> { let mut last_added_location_id = 0; @@ -481,6 +515,7 @@ fn get_kml_timestamp(utc: i64) -> String { .to_string() } +/// Returns a KML document containing a single location with the given timestamp and coordinates. pub fn get_message_kml(timestamp: i64, latitude: f64, longitude: f64) -> String { format!( "\n\ @@ -498,6 +533,7 @@ pub fn get_message_kml(timestamp: i64, latitude: f64, longitude: f64) -> String ) } +/// Sets the timestamp of the last time location was sent in the chat. pub async fn set_kml_sent_timestamp( context: &Context, chat_id: ChatId, @@ -513,6 +549,7 @@ pub async fn set_kml_sent_timestamp( Ok(()) } +/// Sets the location of the message. pub async fn set_msg_location_id(context: &Context, msg_id: MsgId, location_id: u32) -> Result<()> { context .sql diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 184acaae0..43f3e5886 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -799,6 +799,7 @@ impl<'a> MimeFactory<'a> { }) } + /// Returns MIME part with a `message.kml` attachment. fn get_message_kml_part(&self) -> Option { let latitude = self.msg.param.get_float(Param::SetLatitude)?; let longitude = self.msg.param.get_float(Param::SetLongitude)?; @@ -818,6 +819,7 @@ impl<'a> MimeFactory<'a> { Some(part) } + /// Returns MIME part with a `location.kml` attachment. async fn get_location_kml_part(&mut self, context: &Context) -> Result { let (kml_content, last_added_location_id) = location::get_kml(context, self.msg.chat_id).await?; From 1e351bd05f1dfd93b08b57163489b2621cda837c Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 28 Dec 2022 15:09:20 +0000 Subject: [PATCH 05/39] Add documentation to simplify.rs --- src/simplify.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/simplify.rs b/src/simplify.rs index 36daa333b..1c30bc2ef 100644 --- a/src/simplify.rs +++ b/src/simplify.rs @@ -1,13 +1,13 @@ //! # Simplify incoming plaintext. -// protect lines starting with `--` against being treated as a footer. -// for that, we insert a ZERO WIDTH SPACE (ZWSP, 0x200B); -// this should be invisible on most systems and there is no need to unescape it again -// (which won't be done by non-deltas anyway) -// -// this escapes a bit more than actually needed by delta (eg. also lines as "-- footer"), -// but for non-delta-compatibility, that seems to be better. -// (to be only compatible with delta, only "[\r\n|\n]-- {0,2}[\r\n|\n]" needs to be replaced) +/// Protects lines starting with `--` against being treated as a footer. +/// for that, we insert a ZERO WIDTH SPACE (ZWSP, 0x200B); +/// this should be invisible on most systems and there is no need to unescape it again +/// (which won't be done by non-deltas anyway). +/// +/// This escapes a bit more than actually needed by delta (e.g. also lines as "-- footer"), +/// but for non-delta-compatibility, that seems to be better. +/// (to be only compatible with delta, only "[\r\n|\n]-- {0,2}[\r\n|\n]" needs to be replaced) pub fn escape_message_footer_marks(text: &str) -> String { if let Some(text) = text.strip_prefix("--") { "-\u{200B}-".to_string() + &text.replace("\n--", "\n-\u{200B}-") @@ -74,6 +74,7 @@ pub(crate) fn split_lines(buf: &str) -> Vec<&str> { /// Simplified text and some additional information gained from the input. #[derive(Debug, Default)] pub(crate) struct SimplifiedText { + /// The text itself. pub text: String, /// True if the message is forwarded. From 4a982fe632aff23b935e35fcbcb3178395fc7867 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 27 Dec 2022 09:17:19 +0000 Subject: [PATCH 06/39] Add fuzzing tests --- CHANGELOG.md | 1 + README.md | 23 + format-flowed/src/lib.rs | 6 + fuzz/Cargo.lock | 3441 +++++++++++++++++++++++ fuzz/Cargo.toml | 36 + fuzz/fuzz_targets/fuzz_dateparse.rs | 10 + fuzz/fuzz_targets/fuzz_format_flowed.rs | 25 + fuzz/fuzz_targets/fuzz_mailparse.rs | 7 + fuzz/fuzz_targets/fuzz_simplify.rs | 13 + src/fuzzing.rs | 8 + src/lib.rs | 3 + 11 files changed, 3573 insertions(+) create mode 100644 fuzz/Cargo.lock create mode 100644 fuzz/Cargo.toml create mode 100644 fuzz/fuzz_targets/fuzz_dateparse.rs create mode 100644 fuzz/fuzz_targets/fuzz_format_flowed.rs create mode 100644 fuzz/fuzz_targets/fuzz_mailparse.rs create mode 100644 fuzz/fuzz_targets/fuzz_simplify.rs create mode 100644 src/fuzzing.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 9db270c67..706431cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Don't parse the message again after detached signatures validation #3862 - Move format=flowed support to a separate crate #3869 - cargo: bump quick-xml from 0.23.0 to 0.26.0 #3722 +- Add fuzzing tests #3853 ### API-Changes - jsonrpc: add python API for webxdc updates #3872 diff --git a/README.md b/README.md index 71a723eac..3ea334637 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,29 @@ use the `--ignored` argument to the test binary (not to cargo itself): $ cargo test -- --ignored ``` +### Fuzzing + +Install [`cargo-bolero`](https://github.com/camshaft/bolero) with +```sh +$ cargo install cargo-bolero +``` + +Run fuzzing tests with +```sh +$ cd fuzz +$ cargo bolero test fuzz_mailparse --release=false -s NONE +``` + +Corpus is created at `fuzz/fuzz_targets/corpus`, +you can add initial inputs there. +For `fuzz_mailparse` target corpus can be populated with +`../test-data/message/*.eml`. + +To run with AFL instead of libFuzzer: +```sh +$ cargo bolero test fuzz_format_flowed --release=false -e afl -s NONE +``` + ## Features - `vendored`: When using Openssl for TLS, this bundles a vendored version. diff --git a/format-flowed/src/lib.rs b/format-flowed/src/lib.rs index 67d18e8d1..52b6827e5 100644 --- a/format-flowed/src/lib.rs +++ b/format-flowed/src/lib.rs @@ -182,6 +182,12 @@ mod tests { let text = " Foo bar baz"; assert_eq!(format_flowed(text), " Foo bar baz"); + + let text = + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAA"; + let expected = + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA \r\nAAAAAA"; + assert_eq!(format_flowed(text), expected); } #[test] diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock new file mode 100644 index 000000000..b2f3f5f36 --- /dev/null +++ b/fuzz/Cargo.lock @@ -0,0 +1,3441 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" + +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.8", + "once_cell", + "version_check 0.9.4", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" + +[[package]] +name = "ascii_utils" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" + +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-compression" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-imap" +version = "0.6.0" +source = "git+https://github.com/async-email/async-imap?branch=master#85ff7a3d9d71a3715354fabf2fc1a8d047b5710e" +dependencies = [ + "async-channel", + "async-native-tls", + "base64 0.13.1", + "byte-pool", + "chrono", + "futures", + "imap-proto", + "log", + "nom 7.1.1", + "once_cell", + "ouroboros", + "pin-utils", + "stop-token", + "thiserror", + "tokio", +] + +[[package]] +name = "async-native-tls" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d57d4cec3c647232e1094dc013546c0b33ce785d8aeb251e1f20dfaf8a9a13fe" +dependencies = [ + "native-tls", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "async-smtp" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6da21e1dd19fbad3e095ad519fb1558ab77fd82e5c4778dca8f9be0464589e1e" +dependencies = [ + "async-native-tls", + "async-trait", + "base64 0.13.1", + "bufstream", + "fast-socks5", + "futures", + "hostname", + "log", + "nom 7.1.1", + "pin-project", + "pin-utils", + "thiserror", + "tokio", +] + +[[package]] +name = "async-trait" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d1d8ab452a3936018a687b20e6f7cf5363d713b732b8884001317b0e48aa3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async_io_utilities" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b20cffc5590f4bf33f05f97a3ea587feba9c50d20325b401daa096b92ff7da0" +dependencies = [ + "tokio", +] + +[[package]] +name = "async_zip" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a36d43bdefc7215b2b3a97edd03b1553b7969ad76551025eedd3b913c645f6e" +dependencies = [ + "async-compression", + "async_io_utilities", + "chrono", + "crc32fast", + "thiserror", + "tokio", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64ct" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a90ec2df9600c28a01c56c4784c9207a96d2451833aeceb8cc97e4c9548bb78" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + +[[package]] +name = "bolero" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3387d308f66ed222bdbb19c6ba06b1517168c4e45dc64051c5f1b4845db2901c" +dependencies = [ + "bolero-afl", + "bolero-engine", + "bolero-generator", + "bolero-honggfuzz", + "bolero-kani", + "bolero-libfuzzer", + "cfg-if", + "rand 0.8.5", +] + +[[package]] +name = "bolero-afl" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973bc6341b6a865dee93f17b78de4a100551014a527798ff1d7265d3bc0f7d89" +dependencies = [ + "bolero-engine", + "cc", +] + +[[package]] +name = "bolero-engine" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c506a476cea9e95f58c264b343ee279c353d93ceaebe98cbfb16e74bfaee2e2" +dependencies = [ + "anyhow", + "backtrace", + "bolero-generator", + "lazy_static", + "pretty-hex", + "rand 0.8.5", +] + +[[package]] +name = "bolero-generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d52eca8714d110e581cf17eeacf0d1a0d409d38a9e9ce07efeda6125f7febb" +dependencies = [ + "bolero-generator-derive", + "either", + "rand_core 0.6.4", +] + +[[package]] +name = "bolero-generator-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3c57c2a0967ad1a09ba4c2bf8f1c6b6db2f71e8c0db4fa280c65a0f6c249c3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bolero-honggfuzz" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7996a3fa8d93652358b9b3b805233807168f49740a8bf91a531cd61e4da65355" +dependencies = [ + "bolero-engine", +] + +[[package]] +name = "bolero-kani" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206879993fffa1cf2c703b1ef93b0febfa76bae85a0a5d4ae0ee6d99a2e3b74e" +dependencies = [ + "bolero-engine", +] + +[[package]] +name = "bolero-libfuzzer" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc5547411b84703d9020914f15a7d709cfb738c72b5e0f5a499fe56b8465c98" +dependencies = [ + "bolero-engine", + "cc", +] + +[[package]] +name = "buf_redux" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" +dependencies = [ + "memchr", + "safemem", +] + +[[package]] +name = "bufstream" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "byte-pool" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c7230ddbb427b1094d477d821a99f3f54d36333178eeb806e279bcdcecf0ca" +dependencies = [ + "crossbeam-queue", + "stable_deref_trait", +] + +[[package]] +name = "bytemuck" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + +[[package]] +name = "cast5" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b07d673db1ccf000e90f54b819db9e75a8348d6eb056e9b8ab53231b7a9911" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" + +[[package]] +name = "cfb-mode" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" +dependencies = [ + "cipher", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "charset" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e9079d1a12a2cc2bffb5db039c43661836ead4082120d5844f02555aca2d46" +dependencies = [ + "base64 0.13.1", + "encoding_rs", +] + +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "time", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "cipher" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "concurrent-queue" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + +[[package]] +name = "crc24" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd121741cf3eb82c08dd3023eb55bf2665e5f60ec20f89760cf836ae4562e6a0" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "cxx" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "data-encoding" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" + +[[package]] +name = "deltachat" +version = "1.104.0" +dependencies = [ + "anyhow", + "async-channel", + "async-imap", + "async-native-tls", + "async-smtp", + "async_zip", + "backtrace", + "base64 0.13.1", + "bitflags", + "chrono", + "deltachat_derive", + "email", + "encoded-words", + "escaper", + "fast-socks5", + "format-flowed", + "futures", + "futures-lite", + "hex", + "humansize", + "image", + "kamadak-exif", + "lettre_email", + "libc", + "mailparse", + "native-tls", + "num-derive", + "num-traits", + "num_cpus", + "once_cell", + "percent-encoding", + "pgp", + "qrcodegen", + "quick-xml", + "r2d2", + "r2d2_sqlite", + "rand 0.8.5", + "regex", + "reqwest", + "rusqlite", + "rust-hsluv", + "sanitize-filename", + "serde", + "serde_json", + "sha-1", + "sha2 0.10.6", + "smallvec", + "strum", + "strum_macros", + "tagger", + "textwrap", + "thiserror", + "tokio", + "tokio-io-timeout", + "tokio-stream", + "tokio-tar", + "toml", + "trust-dns-resolver", + "url", + "uuid 1.2.2", +] + +[[package]] +name = "deltachat-fuzz" +version = "0.0.0" +dependencies = [ + "bolero", + "deltachat", + "format-flowed", + "mailparse", +] + +[[package]] +name = "deltachat_derive" +version = "2.0.0" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "derive_builder" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" +dependencies = [ + "derive_builder_core", + "syn", +] + +[[package]] +name = "des" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" +dependencies = [ + "cipher", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.3", + "const-oid", + "crypto-common", +] + +[[package]] +name = "ed25519" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "email" +version = "0.0.21" +source = "git+https://github.com/deltachat/rust-email?branch=master#25702df99254d059483b41417cd80696a258df8e" +dependencies = [ + "base64 0.11.0", + "chrono", + "encoded-words", + "encoding", + "lazy_static", + "rand 0.7.3", + "time", + "version_check 0.9.4", +] + +[[package]] +name = "encoded-words" +version = "0.2.0" +source = "git+https://github.com/async-email/encoded-words?branch=master#d55366b36f96e383f39c432aedce42ee8b43f796" +dependencies = [ + "base64 0.12.3", + "charset", + "encoding_rs", + "hex", + "lazy_static", + "regex", + "thiserror", +] + +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +dependencies = [ + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "entities" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" + +[[package]] +name = "enum-as-inner" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "escaper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53eb97b7349ba1bdb31839eceafe9aaae8f1d8d944dc589b67fb0b26e1c1666" +dependencies = [ + "entities", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fast-socks5" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2687b5a6108f18ba8621e0e618a3be1dcc2768632dad24b7cea1f87975375a9" +dependencies = [ + "anyhow", + "log", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "fast_chemail" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4" +dependencies = [ + "ascii_utils", +] + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "filetime" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.42.0", +] + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "format-flowed" +version = "1.0.0" + +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check 0.9.4", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" + +[[package]] +name = "h2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown 0.11.2", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humansize" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e682e2bd70ecbcce5209f11a992a4ba001fea8e60acf7860ce007629e6d2756" +dependencies = [ + "libm", +] + +[[package]] +name = "hyper" +version = "0.14.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", +] + +[[package]] +name = "imap-proto" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73b1b63179418b20aa81002d616c5f21b4ba257da9bca6989ea64dc573933e0" +dependencies = [ + "nom 7.1.1", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipconfig" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" +dependencies = [ + "socket2", + "widestring", + "winapi", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11b0d96e660696543b251e58030cf9787df56da39dab19ad60eae7353040917e" + +[[package]] +name = "itoa" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" + +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kamadak-exif" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4fc70d0ab7e5b6bafa30216a6b48705ea964cdfc29c050f2412295eba58077" +dependencies = [ + "mutate_once", +] + +[[package]] +name = "keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] + +[[package]] +name = "lettre" +version = "0.9.2" +source = "git+https://github.com/deltachat/lettre?branch=master#96555ec428ac114ecfca9934d2fda34c13737e54" +dependencies = [ + "fast_chemail", + "log", +] + +[[package]] +name = "lettre_email" +version = "0.9.2" +source = "git+https://github.com/deltachat/lettre?branch=master#96555ec428ac114ecfca9934d2fda34c13737e54" +dependencies = [ + "base64 0.11.0", + "email", + "lazy_static", + "lettre", + "mime", + "regex", + "time", + "uuid 0.8.2", +] + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "libm" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "libsqlite3-sys" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +dependencies = [ + "cc", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "mailparse" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cae768a50835557749599277fc59f7c728118724eb34185e8feb633ef266a32" +dependencies = [ + "charset", + "data-encoding", + "quoted_printable", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "md-5" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.42.0", +] + +[[package]] +name = "mutate_once" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nom" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" +dependencies = [ + "memchr", + "version_check 0.1.5", +] + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "serde", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "111.24.0+1.1.1s" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3498f259dab01178c6228c6b00dcef0ed2a2d5e20d648c017861227773ea4abd" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" +dependencies = [ + "autocfg", + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ouroboros" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbb50b356159620db6ac971c6d5c9ab788c9cc38a6f49619fca2a27acb062ca" +dependencies = [ + "aliasable", + "ouroboros_macro", +] + +[[package]] +name = "ouroboros_macro" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0d9d1a6191c4f391f87219d1ea42b23f09ee84d64763cd05ee6ea88d9f384d" +dependencies = [ + "Inflector", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys 0.42.0", +] + +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pgp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "991e3f098483f52c454c7cb16720adc010c2966a8845d3c34aad589cb86d3196" +dependencies = [ + "aes", + "base64 0.13.1", + "bitfield", + "block-padding", + "blowfish", + "buf_redux", + "byteorder", + "cast5", + "cfb-mode", + "chrono", + "cipher", + "crc24", + "derive_builder", + "des", + "digest 0.10.6", + "ed25519-dalek", + "flate2", + "generic-array", + "hex", + "log", + "md-5", + "nom 4.2.3", + "num-bigint-dig", + "num-derive", + "num-traits", + "rand 0.8.5", + "ripemd", + "rsa", + "sha1", + "sha2 0.10.6", + "sha3", + "signature", + "smallvec", + "thiserror", + "twofish", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +dependencies = [ + "der", + "pkcs8", + "spki", + "zeroize", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty-hex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa0831dd7cc608c38a5e323422a0077678fa5744aa2be4ad91c4ece8eec8d5" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check 0.9.4", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check 0.9.4", +] + +[[package]] +name = "proc-macro2" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qrcodegen" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-xml" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "quoted_printable" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20f14e071918cbeefc5edc986a7aa92c425dae244e003a35e1cdddb5ca39b5cb" + +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "r2d2_sqlite" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fdc8e4da70586127893be32b7adf21326a4c6b1aba907611edf467d13ffe895" +dependencies = [ + "r2d2", + "rusqlite", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.8", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "reqwest" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +dependencies = [ + "base64 0.13.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "rsa" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" +dependencies = [ + "byteorder", + "digest 0.10.6", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "smallvec", + "subtle", + "zeroize", +] + +[[package]] +name = "rusqlite" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85127183a999f7db96d1a976a309eebbfb6ea3b0b400ddd8340190129de6eb7a" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "memchr", + "smallvec", +] + +[[package]] +name = "rust-hsluv" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efe2374f2385cdd8755a446f80b2a646de603c9d8539ca38734879b5c71e378b" + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustversion" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" + +[[package]] +name = "ryu" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" + +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + +[[package]] +name = "sanitize-filename" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "schannel" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +dependencies = [ + "lazy_static", + "windows-sys 0.36.1", +] + +[[package]] +name = "scheduled-thread-pool" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" + +[[package]] +name = "security-framework" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "sha3" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +dependencies = [ + "digest 0.10.6", + "keccak", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.6", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "smawk" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" + +[[package]] +name = "socket2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel", + "cfg-if", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tagger" +version = "4.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aaa6f5d645d1dae4cd0286e9f8bf15b75a31656348e5e106eb1a940abd34b63" + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.42.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tar" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a50188549787c32c1c3d9c8c71ad7e003ccf2f102489c5a96e385c84760477f4" +dependencies = [ + "filetime", + "futures-core", + "libc", + "redox_syscall", + "tokio", + "tokio-stream", + "xattr", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trust-dns-proto" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.2.3", + "ipnet", + "lazy_static", + "rand 0.8.5", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lazy_static", + "lru-cache", + "parking_lot", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", + "trust-dns-proto", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "twofish" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78e83a30223c757c3947cd144a31014ff04298d8719ae10d03c31c0448c8013" +dependencies = [ + "cipher", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "unicode-linebreak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" +dependencies = [ + "hashbrown 0.12.3", + "regex", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna 0.3.0", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.8", +] + +[[package]] +name = "uuid" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +dependencies = [ + "getrandom 0.2.8", + "serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "web-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "xattr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +dependencies = [ + "libc", +] + +[[package]] +name = "zeroize" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 000000000..a3eba6256 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "deltachat-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[dev-dependencies] +bolero = "0.8" + +[dependencies] +mailparse = "0.13" +deltachat = { path = ".." } +format-flowed = { path = "../format-flowed" } + +[workspace] +members = ["."] + +[[test]] +name = "fuzz_dateparse" +path = "fuzz_targets/fuzz_dateparse.rs" +harness = false + +[[test]] +name = "fuzz_simplify" +path = "fuzz_targets/fuzz_simplify.rs" +harness = false + +[[test]] +name = "fuzz_mailparse" +path = "fuzz_targets/fuzz_mailparse.rs" +harness = false + +[[test]] +name = "fuzz_format_flowed" +path = "fuzz_targets/fuzz_format_flowed.rs" +harness = false diff --git a/fuzz/fuzz_targets/fuzz_dateparse.rs b/fuzz/fuzz_targets/fuzz_dateparse.rs new file mode 100644 index 000000000..e903363db --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_dateparse.rs @@ -0,0 +1,10 @@ +use bolero::check; + +fn main() { + check!().for_each(|data: &[u8]| match std::str::from_utf8(data) { + Ok(input) => { + mailparse::dateparse(input).ok(); + } + Err(_err) => {} + }); +} diff --git a/fuzz/fuzz_targets/fuzz_format_flowed.rs b/fuzz/fuzz_targets/fuzz_format_flowed.rs new file mode 100644 index 000000000..f44bebf94 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_format_flowed.rs @@ -0,0 +1,25 @@ +use bolero::check; +use format_flowed::{format_flowed, unformat_flowed}; + +fn round_trip(input: &str) -> String { + let mut input = format_flowed(input); + input.retain(|c| c != '\r'); + unformat_flowed(&input, false) +} + +fn main() { + check!().for_each(|data: &[u8]| { + if let Ok(input) = std::str::from_utf8(data.into()) { + let mut input = input.to_string(); + + // Only consider inputs that don't contain quotes. + input.retain(|c| c != '>'); + + // Only consider inputs that are the result of unformatting format=flowed text. + // At least this means that lines don't contain any trailing whitespace. + let input = round_trip(&input); + let output = round_trip(&input); + assert_eq!(input, output); + } + }); +} diff --git a/fuzz/fuzz_targets/fuzz_mailparse.rs b/fuzz/fuzz_targets/fuzz_mailparse.rs new file mode 100644 index 000000000..19f2fe097 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_mailparse.rs @@ -0,0 +1,7 @@ +use bolero::check; + +fn main() { + check!().for_each(|data: &[u8]| { + mailparse::parse_mail(data).ok(); + }); +} diff --git a/fuzz/fuzz_targets/fuzz_simplify.rs b/fuzz/fuzz_targets/fuzz_simplify.rs new file mode 100644 index 000000000..cd0a22352 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_simplify.rs @@ -0,0 +1,13 @@ +use bolero::check; + +use deltachat::fuzzing::simplify; + +fn main() { + check!().for_each(|data: &[u8]| match String::from_utf8(data.to_vec()) { + Ok(input) => { + simplify(input.clone(), true); + simplify(input, false); + } + Err(_err) => {} + }); +} diff --git a/src/fuzzing.rs b/src/fuzzing.rs new file mode 100644 index 000000000..85634430c --- /dev/null +++ b/src/fuzzing.rs @@ -0,0 +1,8 @@ +/// Fuzzing target for simplify(). +/// +/// Calls simplify() and panics if simplify() panics. +/// Does not return any vaule to avoid exposing internal crate types. +#[cfg(fuzzing)] +pub fn simplify(mut input: String, is_chat_message: bool) { + crate::simplify::simplify(input, is_chat_message); +} diff --git a/src/lib.rs b/src/lib.rs index a672ec7c0..c69fc8587 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,3 +117,6 @@ pub const DCC_MIME_DEBUG: &str = "DCC_MIME_DEBUG"; mod test_utils; #[cfg(test)] mod tests; + +#[cfg(fuzzing)] +pub mod fuzzing; From 7082f9f882c0516431abd6fb4e8d969b80ce736e Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 28 Dec 2022 19:01:48 +0000 Subject: [PATCH 07/39] Fix fuzzing module warnings --- src/fuzzing.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fuzzing.rs b/src/fuzzing.rs index 85634430c..ad920b9ab 100644 --- a/src/fuzzing.rs +++ b/src/fuzzing.rs @@ -1,8 +1,12 @@ +//! # Fuzzing module. +//! +//! This module exposes private APIs for fuzzing. + /// Fuzzing target for simplify(). /// /// Calls simplify() and panics if simplify() panics. /// Does not return any vaule to avoid exposing internal crate types. #[cfg(fuzzing)] -pub fn simplify(mut input: String, is_chat_message: bool) { +pub fn simplify(input: String, is_chat_message: bool) { crate::simplify::simplify(input, is_chat_message); } From 4e943d52e42786c5a87627d1e30f649a2d72b16c Mon Sep 17 00:00:00 2001 From: Rafael Diniz Date: Wed, 7 Dec 2022 16:20:45 +0300 Subject: [PATCH 08/39] Add mappings for some file types to Viewtype / MIME type Namely: ppt, pptx, xls, heif, heic, avif, txt. But use Viewtype::File for medias without uniform support on all platforms. --- CHANGELOG.md | 1 + python/tests/data/r | 2 ++ python/tests/test_3_offline.py | 17 +++++++++-------- src/message.rs | 14 ++++++++++++-- 4 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 python/tests/data/r diff --git a/CHANGELOG.md b/CHANGELOG.md index 706431cfb..157eb8eb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Move format=flowed support to a separate crate #3869 - cargo: bump quick-xml from 0.23.0 to 0.26.0 #3722 - Add fuzzing tests #3853 +- Add mappings for some file types to Viewtype / MIME type #3881 ### API-Changes - jsonrpc: add python API for webxdc updates #3872 diff --git a/python/tests/data/r b/python/tests/data/r new file mode 100644 index 000000000..3e23ae484 --- /dev/null +++ b/python/tests/data/r @@ -0,0 +1,2 @@ + +hello diff --git a/python/tests/test_3_offline.py b/python/tests/test_3_offline.py index 3a09eebf4..98890287a 100644 --- a/python/tests/test_3_offline.py +++ b/python/tests/test_3_offline.py @@ -450,24 +450,25 @@ class TestOfflineChat: assert msg.filemime == "image/png" @pytest.mark.parametrize( - "typein,typeout", + "fn,typein,typeout", [ - (None, "application/octet-stream"), - ("text/plain", "text/plain"), - ("image/png", "image/png"), + ("r", None, "application/octet-stream"), + ("r.txt", None, "text/plain"), + ("r.txt", "text/plain", "text/plain"), + ("r.txt", "image/png", "image/png"), ], ) - def test_message_file(self, ac1, chat1, data, lp, typein, typeout): + def test_message_file(self, ac1, chat1, data, lp, fn, typein, typeout): lp.sec("sending file") - fn = data.get_path("r.txt") - msg = chat1.send_file(fn, typein) + fp = data.get_path(fn) + msg = chat1.send_file(fp, typein) assert msg assert msg.id > 0 assert msg.is_file() assert os.path.exists(msg.filename) assert msg.filename.endswith(msg.basename) assert msg.filemime == typeout - msg2 = chat1.send_file(fn, typein) + msg2 = chat1.send_file(fp, typein) assert msg2 != msg assert msg2.filename != msg.filename diff --git a/src/message.rs b/src/message.rs index a1e1b0b97..d05b8b366 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1168,6 +1168,7 @@ pub fn guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)> { "3gp" => (Viewtype::Video, "video/3gpp"), "aac" => (Viewtype::Audio, "audio/aac"), "avi" => (Viewtype::Video, "video/x-msvideo"), + "avif" => (Viewtype::File, "image/avif"), // supported since Android 12 / iOS 16 "doc" => (Viewtype::File, "application/msword"), "docx" => ( Viewtype::File, @@ -1176,6 +1177,8 @@ pub fn guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)> { "epub" => (Viewtype::File, "application/epub+zip"), "flac" => (Viewtype::Audio, "audio/flac"), "gif" => (Viewtype::Gif, "image/gif"), + "heic" => (Viewtype::File, "image/heic"), // supported since Android 10 / iOS 11 + "heif" => (Viewtype::File, "image/heif"), // supported since Android 10 / iOS 11 "html" => (Viewtype::File, "text/html"), "htm" => (Viewtype::File, "text/html"), "ico" => (Viewtype::File, "image/vnd.microsoft.icon"), @@ -1200,10 +1203,15 @@ pub fn guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)> { "oga" => (Viewtype::Audio, "audio/ogg"), "ogg" => (Viewtype::Audio, "audio/ogg"), "ogv" => (Viewtype::File, "video/ogg"), - "opus" => (Viewtype::File, "audio/ogg"), // not supported eg. on Android 4 + "opus" => (Viewtype::File, "audio/ogg"), // supported since Android 10 "otf" => (Viewtype::File, "font/otf"), "pdf" => (Viewtype::File, "application/pdf"), "png" => (Viewtype::Image, "image/png"), + "ppt" => (Viewtype::File, "application/vnd.ms-powerpoint"), + "pptx" => ( + Viewtype::File, + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + ), "rar" => (Viewtype::File, "application/vnd.rar"), "rtf" => (Viewtype::File, "application/rtf"), "spx" => (Viewtype::File, "audio/ogg"), // Ogg Speex Profile @@ -1212,6 +1220,7 @@ pub fn guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)> { "tiff" => (Viewtype::File, "image/tiff"), "tif" => (Viewtype::File, "image/tiff"), "ttf" => (Viewtype::File, "font/ttf"), + "txt" => (Viewtype::File, "text/plain"), "vcard" => (Viewtype::File, "text/vcard"), "vcf" => (Viewtype::File, "text/vcard"), "wav" => (Viewtype::File, "audio/wav"), @@ -1221,11 +1230,12 @@ pub fn guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)> { "wmv" => (Viewtype::Video, "video/x-ms-wmv"), "xdc" => (Viewtype::Webxdc, "application/webxdc+zip"), "xhtml" => (Viewtype::File, "application/xhtml+xml"), + "xls" => (Viewtype::File, "application/vnd.ms-excel"), "xlsx" => ( Viewtype::File, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ), - "xml" => (Viewtype::File, "application/vnd.ms-excel"), + "xml" => (Viewtype::File, "application/xml"), "zip" => (Viewtype::File, "application/zip"), _ => { return None; From bf4ad692df79b53d37475aba38a988d38b754050 Mon Sep 17 00:00:00 2001 From: bjoern Date: Fri, 30 Dec 2022 19:53:44 +0100 Subject: [PATCH 09/39] use u32 as id as done elsewhere (#3882) this will avoid some incompatibilities and castingss in UI. --- deltachat-ffi/deltachat.h | 2 +- deltachat-ffi/src/lib.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 4270d0003..4a03f1a8f 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -4763,7 +4763,7 @@ char* dc_contact_get_verifier_addr (dc_contact_t* contact); * we verified the contact ourself. If it is 0, we don't have verifier information or * the contact is not verified. */ -int dc_contact_get_verifier_id (dc_contact_t* contact); +uint32_t dc_contact_get_verifier_id (dc_contact_t* contact); /** diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 51a5d3353..764f1acad 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -3983,10 +3983,10 @@ pub unsafe extern "C" fn dc_contact_get_verifier_addr( } #[no_mangle] -pub unsafe extern "C" fn dc_contact_get_verifier_id(contact: *mut dc_contact_t) -> libc::c_int { +pub unsafe extern "C" fn dc_contact_get_verifier_id(contact: *mut dc_contact_t) -> u32 { if contact.is_null() { eprintln!("ignoring careless call to dc_contact_get_verifier_id()"); - return 0 as libc::c_int; + return 0; } let ffi_contact = &*contact; let ctx = &*ffi_contact.context; @@ -3995,7 +3995,7 @@ pub unsafe extern "C" fn dc_contact_get_verifier_id(contact: *mut dc_contact_t) .unwrap_or_default() .unwrap_or_default(); - contact_id.to_u32() as libc::c_int + contact_id.to_u32() } // dc_lot_t From 45462fb47ef237ef5756b53c5a6e982ca6018371 Mon Sep 17 00:00:00 2001 From: link2xt Date: Sat, 31 Dec 2022 11:46:51 +0000 Subject: [PATCH 10/39] Fix uncaught exception in node JSON-RPC tests Events don't have an `id`, so promises[response.id] does not exist for them. This currently prints a DEP0168 [1] deprecation warning, but will likely return an error in the future. [1] https://nodejs.org/api/all.html#all_deprecations_dep0168-unhandled-exception-in-node-api-callbacks --- .github/workflows/node-tests.yml | 2 ++ CHANGELOG.md | 1 + node/test/test.js | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/node-tests.yml b/.github/workflows/node-tests.yml index 4789de22e..d2f210f39 100644 --- a/.github/workflows/node-tests.yml +++ b/.github/workflows/node-tests.yml @@ -59,6 +59,7 @@ jobs: npm run test env: DCC_NEW_TMP_EMAIL: ${{ secrets.DCC_NEW_TMP_EMAIL }} + NODE_OPTIONS: '--force-node-api-uncaught-exceptions-policy=true' - name: Run tests on Windows, except lint timeout-minutes: 10 if: runner.os == 'Windows' @@ -67,3 +68,4 @@ jobs: npm run test:mocha env: DCC_NEW_TMP_EMAIL: ${{ secrets.DCC_NEW_TMP_EMAIL }} + NODE_OPTIONS: '--force-node-api-uncaught-exceptions-policy=true' diff --git a/CHANGELOG.md b/CHANGELOG.md index 157eb8eb3..8ebb83032 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ ### Fixes - Do not add an error if the message is encrypted but not signed #3860 - Do not strip leading spaces from message lines #3867 +- Fix uncaught exception in JSON-RPC tests #3884 ## 1.104.0 diff --git a/node/test/test.js b/node/test/test.js index 2b4bc6d20..93b5839e3 100644 --- a/node/test/test.js +++ b/node/test/test.js @@ -121,7 +121,7 @@ describe('JSON RPC', function () { const promises = {} dc.startJsonRpcHandler((msg) => { const response = JSON.parse(msg) - promises[response.id](response) + if (response.hasOwnProperty('id')) promises[response.id](response) delete promises[response.id] }) const call = (request) => { From b9dbf1873d25c9db512caab1778ae41c2e199662 Mon Sep 17 00:00:00 2001 From: link2xt Date: Sun, 1 Jan 2023 16:37:39 +0000 Subject: [PATCH 11/39] node: do not truncate assertion errors --- node/test/test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/node/test/test.js b/node/test/test.js index 93b5839e3..3d6c93de9 100644 --- a/node/test/test.js +++ b/node/test/test.js @@ -11,6 +11,7 @@ import { mkdtempSync, statSync } from 'fs' import { tmpdir } from 'os' import { Context } from '../dist/context' chai.use(chaiAsPromised) +chai.config.truncateThreshold = 0; // Do not truncate assertion errors. async function createTempUser(url) { const fetch = require('node-fetch') From 4bbb83826cf10e3b7eebd8d71489398c32438c93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 21:01:06 +0000 Subject: [PATCH 12/39] cargo: bump thiserror from 1.0.37 to 1.0.38 Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.37 to 1.0.38. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.37...1.0.38) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33f9f9eda..cfdf8853c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3482,18 +3482,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", From bcef1c7a76aa384c0b9d1aa95ed52abd5794d067 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 21:01:13 +0000 Subject: [PATCH 13/39] cargo: bump num_cpus from 1.14.0 to 1.15.0 Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.14.0 to 1.15.0. - [Release notes](https://github.com/seanmonstar/num_cpus/releases) - [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md) - [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.14.0...v1.15.0) --- updated-dependencies: - dependency-name: num_cpus dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33f9f9eda..4d3ff0b57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2336,11 +2336,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi 0.2.6", "libc", ] diff --git a/Cargo.toml b/Cargo.toml index a76e6d5c7..f260f6eec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ libc = "0.2" log = {version = "0.4.16", optional = true } mailparse = "0.13" native-tls = "0.2" -num_cpus = "1.14" +num_cpus = "1.15" num-derive = "0.3" num-traits = "0.2" once_cell = "1.16.0" From a562348dfae1857cb33bc5b5b92179f46c7c434c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 21:01:22 +0000 Subject: [PATCH 14/39] cargo: bump anyhow from 1.0.66 to 1.0.68 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.66 to 1.0.68. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.66...1.0.68) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33f9f9eda..577246655 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "ascii_utils" From cb4b9fce303c3d75b8033c0689431c0a489fc7a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 21:01:55 +0000 Subject: [PATCH 15/39] cargo: bump syn from 1.0.105 to 1.0.107 Bumps [syn](https://github.com/dtolnay/syn) from 1.0.105 to 1.0.107. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.105...1.0.107) --- updated-dependencies: - dependency-name: syn dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33f9f9eda..48e8cb505 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3413,9 +3413,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", From 4e468fdf2403edafaaa5e5ce72c4d124b29e46ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 21:02:06 +0000 Subject: [PATCH 16/39] cargo: bump humansize from 2.1.2 to 2.1.3 Bumps [humansize](https://github.com/LeopoldArkham/humansize) from 2.1.2 to 2.1.3. - [Release notes](https://github.com/LeopoldArkham/humansize/releases) - [Changelog](https://github.com/LeopoldArkham/humansize/blob/master/changelog.md) - [Commits](https://github.com/LeopoldArkham/humansize/commits) --- updated-dependencies: - dependency-name: humansize dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33f9f9eda..afdbcc0ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1752,9 +1752,9 @@ dependencies = [ [[package]] name = "humansize" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e682e2bd70ecbcce5209f11a992a4ba001fea8e60acf7860ce007629e6d2756" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" dependencies = [ "libm", ] From 15fad5476ee945b097ef99e590c3e2341d98c31c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 21:02:20 +0000 Subject: [PATCH 17/39] cargo: bump tokio from 1.22.0 to 1.23.0 Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.22.0 to 1.23.0. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.22.0...tokio-1.23.0) --- updated-dependencies: - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- deltachat-jsonrpc/Cargo.toml | 4 ++-- deltachat-rpc-server/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33f9f9eda..cdecc713f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3538,9 +3538,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ "autocfg", "bytes", @@ -3553,7 +3553,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.42.0", ] [[package]] diff --git a/deltachat-jsonrpc/Cargo.toml b/deltachat-jsonrpc/Cargo.toml index c8d77c5b9..dbe8b2d17 100644 --- a/deltachat-jsonrpc/Cargo.toml +++ b/deltachat-jsonrpc/Cargo.toml @@ -23,7 +23,7 @@ futures = { version = "0.3.25" } serde_json = "1.0.89" yerpc = { version = "^0.3.1", features = ["anyhow_expose"] } typescript-type-def = { version = "0.5.5", features = ["json_value"] } -tokio = { version = "1.22.0" } +tokio = { version = "1.23.0" } sanitize-filename = "0.4" walkdir = "2.3.2" @@ -32,7 +32,7 @@ axum = { version = "0.6.1", optional = true, features = ["ws"] } env_logger = { version = "0.10.0", optional = true } [dev-dependencies] -tokio = { version = "1.22.0", features = ["full", "rt-multi-thread"] } +tokio = { version = "1.23.0", features = ["full", "rt-multi-thread"] } [features] diff --git a/deltachat-rpc-server/Cargo.toml b/deltachat-rpc-server/Cargo.toml index 49c568bd9..b6f10996d 100644 --- a/deltachat-rpc-server/Cargo.toml +++ b/deltachat-rpc-server/Cargo.toml @@ -21,5 +21,5 @@ futures-lite = "1.12.0" log = "0.4" serde_json = "1.0.89" serde = { version = "1.0", features = ["derive"] } -tokio = { version = "1.22.0", features = ["io-std"] } +tokio = { version = "1.23.0", features = ["io-std"] } yerpc = { version = "0.3.1", features = ["anyhow_expose"] } From 11ca12e43cd4236cdea944109c71a84394d4f181 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 21:02:53 +0000 Subject: [PATCH 18/39] cargo: bump backtrace from 0.3.66 to 0.3.67 Bumps [backtrace](https://github.com/rust-lang/backtrace-rs) from 0.3.66 to 0.3.67. - [Release notes](https://github.com/rust-lang/backtrace-rs/releases) - [Commits](https://github.com/rust-lang/backtrace-rs/compare/0.3.66...0.3.67) --- updated-dependencies: - dependency-name: backtrace dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33f9f9eda..030b771f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ "gimli", ] @@ -340,15 +340,15 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", "cfg-if", "libc", - "miniz_oxide 0.5.3", + "miniz_oxide 0.6.2", "object", "rustc-demangle", ] @@ -1598,9 +1598,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.26.2" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" [[package]] name = "h2" @@ -2346,9 +2346,9 @@ dependencies = [ [[package]] name = "object" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" dependencies = [ "memchr", ] From de47aa84662dadb344b8da21da1601d780634bd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Jan 2023 23:24:38 +0000 Subject: [PATCH 19/39] cargo: bump mailparse from 0.13.8 to 0.14.0 Bumps [mailparse](https://github.com/staktrace/mailparse) from 0.13.8 to 0.14.0. - [Release notes](https://github.com/staktrace/mailparse/releases) - [Commits](https://github.com/staktrace/mailparse/compare/v0.13.8...v0.14.0) --- updated-dependencies: - dependency-name: mailparse dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b37c0598..89d0bd083 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -861,9 +861,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" [[package]] name = "deltachat" @@ -2100,9 +2100,9 @@ dependencies = [ [[package]] name = "mailparse" -version = "0.13.8" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cae768a50835557749599277fc59f7c728118724eb34185e8feb633ef266a32" +checksum = "6b56570f5f8c0047260d1c8b5b331f62eb9c660b9dd4071a8c46f8c7d3f280aa" dependencies = [ "charset", "data-encoding", @@ -2757,9 +2757,9 @@ dependencies = [ [[package]] name = "quoted_printable" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fee2dce59f7a43418e3382c766554c614e06a552d53a8f07ef499ea4b332c0f" +checksum = "20f14e071918cbeefc5edc986a7aa92c425dae244e003a35e1cdddb5ca39b5cb" [[package]] name = "r2d2" diff --git a/Cargo.toml b/Cargo.toml index f260f6eec..1c9d7230e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ kamadak-exif = "0.5" lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" } libc = "0.2" log = {version = "0.4.16", optional = true } -mailparse = "0.13" +mailparse = "0.14" native-tls = "0.2" num_cpus = "1.15" num-derive = "0.3" From 035b711ee337fe0e15bfed34fcbc7580fd01a351 Mon Sep 17 00:00:00 2001 From: link2xt Date: Sun, 1 Jan 2023 18:57:28 +0000 Subject: [PATCH 20/39] Buffer IMAP client writes async-imap does not do its own buffering, but calls flush() after sending each command. Using BufWriter reduces the number of write() system calls used to send a single command. Note that BufWriter is set up on top of TLS streams, because we can't guarantee that TLS libraries flush the stream before waiting for response. --- CHANGELOG.md | 1 + src/imap.rs | 29 +++++----- src/imap/client.rs | 129 +++++++++++++++++++++----------------------- src/imap/session.rs | 12 +++-- src/lib.rs | 1 + src/net.rs | 26 +++++++++ src/socks.rs | 16 ++---- 7 files changed, 118 insertions(+), 96 deletions(-) create mode 100644 src/net.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ebb83032..c58c4f608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - cargo: bump quick-xml from 0.23.0 to 0.26.0 #3722 - Add fuzzing tests #3853 - Add mappings for some file types to Viewtype / MIME type #3881 +- Buffer IMAP client writes #3888 ### API-Changes - jsonrpc: add python API for webxdc updates #3872 diff --git a/src/imap.rs b/src/imap.rs index 64dd59976..c762cae7b 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -304,22 +304,23 @@ impl Imap { let imap_server: &str = config.lp.server.as_ref(); let imap_port = config.lp.port; - let connection = if let Some(socks5_config) = &config.socks5_config { - Client::connect_insecure_socks5((imap_server, imap_port), socks5_config.clone()) + if let Some(socks5_config) = &config.socks5_config { + if config.lp.security == Socket::Starttls { + Client::connect_starttls_socks5( + imap_server, + imap_port, + socks5_config.clone(), + config.strict_tls, + ) .await + } else { + Client::connect_insecure_socks5((imap_server, imap_port), socks5_config.clone()) + .await + } + } else if config.lp.security == Socket::Starttls { + Client::connect_starttls(imap_server, imap_port, config.strict_tls).await } else { Client::connect_insecure((imap_server, imap_port)).await - }; - - match connection { - Ok(client) => { - if config.lp.security == Socket::Starttls { - client.secure(imap_server, config.strict_tls).await - } else { - Ok(client) - } - } - Err(err) => Err(err), } } else { let config = &self.config; @@ -328,8 +329,8 @@ impl Imap { if let Some(socks5_config) = &config.socks5_config { Client::connect_secure_socks5( - (imap_server, imap_port), imap_server, + imap_port, config.strict_tls, socks5_config.clone(), ) diff --git a/src/imap/client.rs b/src/imap/client.rs index eef6e7929..7a2329c6a 100644 --- a/src/imap/client.rs +++ b/src/imap/client.rs @@ -8,13 +8,13 @@ use anyhow::{Context as _, Result}; use async_imap::Client as ImapClient; use async_imap::Session as ImapSession; -use tokio::net::{self, TcpStream}; -use tokio::time::timeout; -use tokio_io_timeout::TimeoutStream; +use tokio::io::BufWriter; +use tokio::net::ToSocketAddrs; use super::capabilities::Capabilities; use super::session::Session; use crate::login_param::build_tls; +use crate::net::connect_tcp; use crate::socks::Socks5Config; use super::session::SessionStream; @@ -24,7 +24,6 @@ pub(crate) const IMAP_TIMEOUT: Duration = Duration::from_secs(30); #[derive(Debug)] pub(crate) struct Client { - is_secure: bool, inner: ImapClient>, } @@ -93,108 +92,104 @@ impl Client { } pub async fn connect_secure(hostname: &str, port: u16, strict_tls: bool) -> Result { - let tcp_stream = timeout(IMAP_TIMEOUT, TcpStream::connect((hostname, port))).await??; - let mut timeout_stream = TimeoutStream::new(tcp_stream); - timeout_stream.set_write_timeout(Some(IMAP_TIMEOUT)); - timeout_stream.set_read_timeout(Some(IMAP_TIMEOUT)); - let timeout_stream = Box::pin(timeout_stream); - + let tcp_stream = connect_tcp((hostname, port), IMAP_TIMEOUT).await?; let tls = build_tls(strict_tls); - let tls_stream: Box = - Box::new(tls.connect(hostname, timeout_stream).await?); - let mut client = ImapClient::new(tls_stream); + let tls_stream = tls.connect(hostname, tcp_stream).await?; + let buffered_stream = BufWriter::new(tls_stream); + let session_stream: Box = Box::new(buffered_stream); + let mut client = ImapClient::new(session_stream); let _greeting = client .read_response() .await .context("failed to read greeting")?; - Ok(Client { - is_secure: true, - inner: client, - }) + Ok(Client { inner: client }) } - pub async fn connect_insecure(addr: impl net::ToSocketAddrs) -> Result { - let tcp_stream = timeout(IMAP_TIMEOUT, TcpStream::connect(addr)).await??; - let mut timeout_stream = TimeoutStream::new(tcp_stream); - timeout_stream.set_write_timeout(Some(IMAP_TIMEOUT)); - timeout_stream.set_read_timeout(Some(IMAP_TIMEOUT)); - let timeout_stream = Box::pin(timeout_stream); - let stream: Box = Box::new(timeout_stream); - - let mut client = ImapClient::new(stream); + pub async fn connect_insecure(addr: impl ToSocketAddrs) -> Result { + let tcp_stream = connect_tcp(addr, IMAP_TIMEOUT).await?; + let buffered_stream = BufWriter::new(tcp_stream); + let session_stream: Box = Box::new(buffered_stream); + let mut client = ImapClient::new(session_stream); let _greeting = client .read_response() .await .context("failed to read greeting")?; - Ok(Client { - is_secure: false, - inner: client, - }) + Ok(Client { inner: client }) + } + + pub async fn connect_starttls(hostname: &str, port: u16, strict_tls: bool) -> Result { + let tcp_stream = connect_tcp((hostname, port), IMAP_TIMEOUT).await?; + let tls = build_tls(strict_tls); + let tls_stream = tls.connect(hostname, tcp_stream).await?; + let buffered_stream = BufWriter::new(tls_stream); + let session_stream: Box = Box::new(buffered_stream); + let mut client = ImapClient::new(session_stream); + let _greeting = client + .read_response() + .await + .context("failed to read greeting")?; + + Ok(Client { inner: client }) } pub async fn connect_secure_socks5( - target_addr: impl net::ToSocketAddrs, domain: &str, + port: u16, strict_tls: bool, socks5_config: Socks5Config, ) -> Result { - let socks5_stream: Box = - Box::new(socks5_config.connect(target_addr, IMAP_TIMEOUT).await?); - + let socks5_stream = socks5_config.connect((domain, port), IMAP_TIMEOUT).await?; let tls = build_tls(strict_tls); - let tls_stream: Box = - Box::new(tls.connect(domain, socks5_stream).await?); - let mut client = ImapClient::new(tls_stream); - + let tls_stream = tls.connect(domain, socks5_stream).await?; + let buffered_stream = BufWriter::new(tls_stream); + let session_stream: Box = Box::new(buffered_stream); + let mut client = ImapClient::new(session_stream); let _greeting = client .read_response() .await .context("failed to read greeting")?; - Ok(Client { - is_secure: true, - inner: client, - }) + Ok(Client { inner: client }) } pub async fn connect_insecure_socks5( - target_addr: impl net::ToSocketAddrs, + target_addr: impl ToSocketAddrs, socks5_config: Socks5Config, ) -> Result { - let socks5_stream: Box = - Box::new(socks5_config.connect(target_addr, IMAP_TIMEOUT).await?); - - let mut client = ImapClient::new(socks5_stream); + let socks5_stream = socks5_config.connect(target_addr, IMAP_TIMEOUT).await?; + let buffered_stream = BufWriter::new(socks5_stream); + let session_stream: Box = Box::new(buffered_stream); + let mut client = ImapClient::new(session_stream); let _greeting = client .read_response() .await .context("failed to read greeting")?; - Ok(Client { - is_secure: false, - inner: client, - }) + Ok(Client { inner: client }) } - pub async fn secure(self, domain: &str, strict_tls: bool) -> Result { - if self.is_secure { - Ok(self) - } else { - let Client { mut inner, .. } = self; - let tls = build_tls(strict_tls); - inner.run_command_and_check_ok("STARTTLS", None).await?; + pub async fn connect_starttls_socks5( + hostname: &str, + port: u16, + socks5_config: Socks5Config, + strict_tls: bool, + ) -> Result { + let socks5_stream = socks5_config + .connect((hostname, port), IMAP_TIMEOUT) + .await?; + let tls = build_tls(strict_tls); + let tls_stream = tls.connect(hostname, socks5_stream).await?; + let buffered_stream = BufWriter::new(tls_stream); + let session_stream: Box = Box::new(buffered_stream); + let mut client = ImapClient::new(session_stream); + let _greeting = client + .read_response() + .await + .context("failed to read greeting")?; - let stream = inner.into_inner(); - let ssl_stream = tls.connect(domain, stream).await?; - let boxed: Box = Box::new(ssl_stream); - - Ok(Client { - is_secure: true, - inner: ImapClient::new(boxed), - }) - } + Ok(Client { inner: client }) } } diff --git a/src/imap/session.rs b/src/imap/session.rs index a66dd4852..f3dd00a86 100644 --- a/src/imap/session.rs +++ b/src/imap/session.rs @@ -6,6 +6,7 @@ use async_imap::types::Mailbox; use async_imap::Session as ImapSession; use async_native_tls::TlsStream; use fast_socks5::client::Socks5Stream; +use tokio::io::BufWriter; use tokio::net::TcpStream; use tokio_io_timeout::TimeoutStream; @@ -33,12 +34,17 @@ pub(crate) trait SessionStream: fn set_read_timeout(&mut self, timeout: Option); } -impl SessionStream for TlsStream> { +impl SessionStream for Box { + fn set_read_timeout(&mut self, timeout: Option) { + self.as_mut().set_read_timeout(timeout); + } +} +impl SessionStream for TlsStream { fn set_read_timeout(&mut self, timeout: Option) { self.get_mut().set_read_timeout(timeout); } } -impl SessionStream for TlsStream>>> { +impl SessionStream for BufWriter { fn set_read_timeout(&mut self, timeout: Option) { self.get_mut().set_read_timeout(timeout); } @@ -48,7 +54,7 @@ impl SessionStream for Pin>> { self.as_mut().set_read_timeout_pinned(timeout); } } -impl SessionStream for Socks5Stream>>> { +impl SessionStream for Socks5Stream { fn set_read_timeout(&mut self, timeout: Option) { self.get_socket_mut().set_read_timeout(timeout) } diff --git a/src/lib.rs b/src/lib.rs index c69fc8587..a6e8eb8ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,7 @@ mod dehtml; mod authres; mod color; pub mod html; +mod net; pub mod plaintext; mod ratelimit; pub mod summary; diff --git a/src/net.rs b/src/net.rs new file mode 100644 index 000000000..53855cb74 --- /dev/null +++ b/src/net.rs @@ -0,0 +1,26 @@ +///! # Common network utilities. +use std::pin::Pin; +use std::time::Duration; + +use anyhow::{Context as _, Result}; +use tokio::net::{TcpStream, ToSocketAddrs}; +use tokio::time::timeout; +use tokio_io_timeout::TimeoutStream; + +/// Returns a TCP connection with read/write timeouts set. +pub(crate) async fn connect_tcp( + addr: impl ToSocketAddrs, + timeout_val: Duration, +) -> Result>>> { + let tcp_stream = timeout(timeout_val, TcpStream::connect(addr)) + .await + .context("connection timeout")? + .context("connection failure")?; + + let mut timeout_stream = TimeoutStream::new(tcp_stream); + timeout_stream.set_write_timeout(Some(timeout_val)); + timeout_stream.set_read_timeout(Some(timeout_val)); + let pinned_stream = Box::pin(timeout_stream); + + Ok(pinned_stream) +} diff --git a/src/socks.rs b/src/socks.rs index 89a9458c6..e7ea20730 100644 --- a/src/socks.rs +++ b/src/socks.rs @@ -4,10 +4,10 @@ use std::fmt; use std::pin::Pin; use std::time::Duration; -use anyhow::{Context as _, Result}; +use crate::net::connect_tcp; +use anyhow::Result; pub use async_smtp::ServerAddress; use tokio::net::{self, TcpStream}; -use tokio::time::timeout; use tokio_io_timeout::TimeoutStream; use crate::context::Context; @@ -59,14 +59,7 @@ impl Socks5Config { target_addr: impl net::ToSocketAddrs, timeout_val: Duration, ) -> Result>>>> { - let tcp_stream = timeout(timeout_val, TcpStream::connect(target_addr)) - .await - .context("connection timeout")? - .context("connection failure")?; - let mut timeout_stream = TimeoutStream::new(tcp_stream); - timeout_stream.set_write_timeout(Some(timeout_val)); - timeout_stream.set_read_timeout(Some(timeout_val)); - let timeout_stream = Box::pin(timeout_stream); + let tcp_stream = connect_tcp(target_addr, timeout_val).await?; let authentication_method = if let Some((username, password)) = self.user_password.as_ref() { @@ -78,8 +71,7 @@ impl Socks5Config { None }; let socks_stream = - Socks5Stream::use_stream(timeout_stream, authentication_method, Config::default()) - .await?; + Socks5Stream::use_stream(tcp_stream, authentication_method, Config::default()).await?; Ok(socks_stream) } From 08af7419aff1529fca0efbbc9345547ce3efaff9 Mon Sep 17 00:00:00 2001 From: link2xt Date: Sun, 1 Jan 2023 18:30:05 +0300 Subject: [PATCH 21/39] Format configuration error with causes --- src/configure.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/configure.rs b/src/configure.rs index 63e85dcd6..8610e97dc 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -582,7 +582,7 @@ async fn try_imap_one_param( info!(context, "failure: {}", err); return Err(ConfigurationError { config: inf, - msg: err.to_string(), + msg: format!("{:#}", err), }); } Ok(imap) => imap, @@ -593,7 +593,7 @@ async fn try_imap_one_param( info!(context, "failure: {}", err); Err(ConfigurationError { config: inf, - msg: err.to_string(), + msg: format!("{:#}", err), }) } Ok(()) => { @@ -634,7 +634,7 @@ async fn try_smtp_one_param( info!(context, "failure: {}", err); Err(ConfigurationError { config: inf, - msg: err.to_string(), + msg: format!("{:#}", err), }) } else { info!(context, "success: {}", inf); From 9aaf5cf914692aacd7fa9d9ba7bb6fdddcce0f70 Mon Sep 17 00:00:00 2001 From: link2xt Date: Sun, 1 Jan 2023 22:50:20 +0000 Subject: [PATCH 22/39] Disable Nagle's algorithm for TCP connections --- src/net.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/net.rs b/src/net.rs index 53855cb74..6c0c7dd0b 100644 --- a/src/net.rs +++ b/src/net.rs @@ -7,7 +7,11 @@ use tokio::net::{TcpStream, ToSocketAddrs}; use tokio::time::timeout; use tokio_io_timeout::TimeoutStream; -/// Returns a TCP connection with read/write timeouts set. +/// Returns a TCP connection stream with read/write timeouts set +/// and Nagle's algorithm disabled with `TCP_NODELAY`. +/// +/// `TCP_NODELAY` ensures writing to the stream always results in immediate sending of the packet +/// to the network, which is important to reduce the latency of interactive protocols such as IMAP. pub(crate) async fn connect_tcp( addr: impl ToSocketAddrs, timeout_val: Duration, @@ -17,6 +21,9 @@ pub(crate) async fn connect_tcp( .context("connection timeout")? .context("connection failure")?; + // Disable Nagle's algorithm. + tcp_stream.set_nodelay(true)?; + let mut timeout_stream = TimeoutStream::new(tcp_stream); timeout_stream.set_write_timeout(Some(timeout_val)); timeout_stream.set_read_timeout(Some(timeout_val)); From 4489db76c903a27c28886e238a2a3feef316736f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:43:57 +0000 Subject: [PATCH 23/39] cargo: bump quote from 1.0.21 to 1.0.23 Bumps [quote](https://github.com/dtolnay/quote) from 1.0.21 to 1.0.23. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.21...1.0.23) --- updated-dependencies: - dependency-name: quote dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00ca5046f..386c22fcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2748,9 +2748,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] From e6324e3a198a776d15885734ad1aed54469b503b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:44:38 +0000 Subject: [PATCH 24/39] cargo: bump libc from 0.2.137 to 0.2.139 Bumps [libc](https://github.com/rust-lang/libc) from 0.2.137 to 0.2.139. - [Release notes](https://github.com/rust-lang/libc/releases) - [Commits](https://github.com/rust-lang/libc/compare/0.2.137...0.2.139) --- updated-dependencies: - dependency-name: libc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00ca5046f..194030be5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2030,9 +2030,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.137" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libm" From f694d2e150cd66622cb2437391e1a13f09fd98c4 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 2 Jan 2023 21:26:46 +0000 Subject: [PATCH 25/39] Format configure() logs with error causes --- src/configure.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/configure.rs b/src/configure.rs index 8610e97dc..82403a76a 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -579,7 +579,7 @@ async fn try_imap_one_param( let mut imap = match Imap::new(param, socks5_config.clone(), addr, provider_strict_tls, r) { Err(err) => { - info!(context, "failure: {}", err); + info!(context, "failure: {:#}", err); return Err(ConfigurationError { config: inf, msg: format!("{:#}", err), @@ -590,7 +590,7 @@ async fn try_imap_one_param( match imap.connect(context).await { Err(err) => { - info!(context, "failure: {}", err); + info!(context, "failure: {:#}", err); Err(ConfigurationError { config: inf, msg: format!("{:#}", err), From 1e5c90ed65655ac717f9d430bf5d71b4d56eaf5f Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 2 Jan 2023 20:01:34 +0000 Subject: [PATCH 26/39] Fix STARTTLS connection --- src/imap/client.rs | 55 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/src/imap/client.rs b/src/imap/client.rs index 7a2329c6a..74624a119 100644 --- a/src/imap/client.rs +++ b/src/imap/client.rs @@ -102,7 +102,7 @@ impl Client { let _greeting = client .read_response() .await - .context("failed to read greeting")?; + .context("failed to read greeting")??; Ok(Client { inner: client }) } @@ -115,22 +115,36 @@ impl Client { let _greeting = client .read_response() .await - .context("failed to read greeting")?; + .context("failed to read greeting")??; Ok(Client { inner: client }) } pub async fn connect_starttls(hostname: &str, port: u16, strict_tls: bool) -> Result { let tcp_stream = connect_tcp((hostname, port), IMAP_TIMEOUT).await?; - let tls = build_tls(strict_tls); - let tls_stream = tls.connect(hostname, tcp_stream).await?; - let buffered_stream = BufWriter::new(tls_stream); - let session_stream: Box = Box::new(buffered_stream); + + // Run STARTTLS command and convert the client back into a stream. + let session_stream: Box = Box::new(tcp_stream); let mut client = ImapClient::new(session_stream); let _greeting = client .read_response() .await - .context("failed to read greeting")?; + .context("failed to read greeting")??; + client + .run_command_and_check_ok("STARTTLS", None) + .await + .context("STARTTLS command failed")?; + let tcp_stream = client.into_inner(); + + let tls = build_tls(strict_tls); + let tls_stream = tls + .connect(hostname, tcp_stream) + .await + .context("STARTTLS upgrade failed")?; + + let buffered_stream = BufWriter::new(tls_stream); + let session_stream: Box = Box::new(buffered_stream); + let client = ImapClient::new(session_stream); Ok(Client { inner: client }) } @@ -150,7 +164,7 @@ impl Client { let _greeting = client .read_response() .await - .context("failed to read greeting")?; + .context("failed to read greeting")??; Ok(Client { inner: client }) } @@ -166,7 +180,7 @@ impl Client { let _greeting = client .read_response() .await - .context("failed to read greeting")?; + .context("failed to read greeting")??; Ok(Client { inner: client }) } @@ -180,15 +194,28 @@ impl Client { let socks5_stream = socks5_config .connect((hostname, port), IMAP_TIMEOUT) .await?; - let tls = build_tls(strict_tls); - let tls_stream = tls.connect(hostname, socks5_stream).await?; - let buffered_stream = BufWriter::new(tls_stream); - let session_stream: Box = Box::new(buffered_stream); + + // Run STARTTLS command and convert the client back into a stream. + let session_stream: Box = Box::new(socks5_stream); let mut client = ImapClient::new(session_stream); let _greeting = client .read_response() .await - .context("failed to read greeting")?; + .context("failed to read greeting")??; + client + .run_command_and_check_ok("STARTTLS", None) + .await + .context("STARTTLS command failed")?; + let socks5_stream = client.into_inner(); + + let tls = build_tls(strict_tls); + let tls_stream = tls + .connect(hostname, socks5_stream) + .await + .context("STARTTLS upgrade failed")?; + let buffered_stream = BufWriter::new(tls_stream); + let session_stream: Box = Box::new(buffered_stream); + let client = ImapClient::new(session_stream); Ok(Client { inner: client }) } From 5b3596987bbaa388b90569e70eced6791846c34b Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 2 Jan 2023 21:31:23 +0000 Subject: [PATCH 27/39] Test that STARTTLS connection works --- .../src/deltachat_rpc_client/pytestplugin.py | 9 +++++++-- deltachat-rpc-client/tests/test_something.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py b/deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py index f628fdcfa..4b8562af7 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py @@ -27,12 +27,17 @@ class ACFactory: async def get_unconfigured_bot(self) -> Bot: return Bot(await self.get_unconfigured_account()) - async def new_configured_account(self) -> Account: + async def new_preconfigured_account(self) -> Account: + """Make a new account with configuration options set, but configuration not started.""" credentials = await get_temp_credentials() account = await self.get_unconfigured_account() - assert not await account.is_configured() await account.set_config("addr", credentials["email"]) await account.set_config("mail_pw", credentials["password"]) + assert not await account.is_configured() + return account + + async def new_configured_account(self) -> Account: + account = await self.new_preconfigured_account() await account.configure() assert await account.is_configured() return account diff --git a/deltachat-rpc-client/tests/test_something.py b/deltachat-rpc-client/tests/test_something.py index 5b2e67af9..d1208042e 100644 --- a/deltachat-rpc-client/tests/test_something.py +++ b/deltachat-rpc-client/tests/test_something.py @@ -41,6 +41,16 @@ async def test_acfactory(acfactory) -> None: print("Successful configuration") +@pytest.mark.asyncio +async def test_configure_starttls(acfactory) -> None: + account = await acfactory.new_preconfigured_account() + + # Use STARTTLS + await account.set_config("mail_security", "2") + await account.configure() + assert await account.is_configured() + + @pytest.mark.asyncio async def test_account(acfactory) -> None: alice, bob = await acfactory.get_online_accounts(2) From 7aa7548a51e93faed1cb0f332166fbdbbc828c6f Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 2 Jan 2023 21:34:45 +0000 Subject: [PATCH 28/39] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c58c4f608..476504be4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - Do not add an error if the message is encrypted but not signed #3860 - Do not strip leading spaces from message lines #3867 - Fix uncaught exception in JSON-RPC tests #3884 +- Fix STARTTLS connection and add a test for it #3907 ## 1.104.0 From c8f0c6b5f65312129edb9a65e29177d519aad0a2 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 3 Jan 2023 12:06:27 +0000 Subject: [PATCH 29/39] Add more IMAP logs --- src/imap.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index c762cae7b..2df278f29 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -297,6 +297,7 @@ impl Imap { let oauth2 = self.config.lp.oauth2; + info!(context, "Connecting to IMAP server"); let connection_res: Result = if self.config.lp.security == Socket::Starttls || self.config.lp.security == Socket::Plain { @@ -346,6 +347,7 @@ impl Imap { let imap_pw: &str = config.lp.password.as_ref(); let login_res = if oauth2 { + info!(context, "Logging into IMAP server with OAuth 2"); let addr: &str = config.addr.as_ref(); let token = get_oauth2_access_token(context, addr, imap_pw, true) @@ -357,6 +359,7 @@ impl Imap { }; client.authenticate("XOAUTH2", auth).await } else { + info!(context, "Logging into IMAP server with LOGIN"); client.login(imap_user, imap_pw).await }; @@ -372,6 +375,7 @@ impl Imap { "IMAP-LOGIN as {}", self.config.lp.user ))); + info!(context, "Successfully logged into IMAP server"); Ok(()) } @@ -379,7 +383,7 @@ impl Imap { let imap_user = self.config.lp.user.to_owned(); let message = stock_str::cannot_login(context, &imap_user).await; - warn!(context, "{} ({})", message, err); + warn!(context, "{} ({:#})", message, err); let lock = context.wrong_pw_warning_mutex.lock().await; if self.login_failed_once @@ -387,7 +391,7 @@ impl Imap { && context.get_config_bool(Config::NotifyAboutWrongPw).await? { if let Err(e) = context.set_config(Config::NotifyAboutWrongPw, None).await { - warn!(context, "{}", e); + warn!(context, "{:#}", e); } drop(lock); @@ -397,13 +401,13 @@ impl Imap { chat::add_device_msg_with_importance(context, None, Some(&mut msg), true) .await { - warn!(context, "{}", e); + warn!(context, "{:#}", e); } } else { self.login_failed_once = true; } - Err(format_err!("{}\n\n{}", message, err)) + Err(format_err!("{}\n\n{:#}", message, err)) } } } @@ -846,7 +850,7 @@ impl Imap { if let Some(folder) = context.get_config(*config).await? { self.fetch_new_messages(context, &folder, false, true) .await - .context("could not fetch messages")?; + .context("could not fetch existing messages")?; } } } From f0a28b916821cc608509d7b1678bbf591422457e Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 3 Jan 2023 12:08:24 +0000 Subject: [PATCH 30/39] Log the error before triggering reconnect This way "Dropping an IMAP connection" message appears after the cause for connection drop. --- src/scheduler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scheduler.rs b/src/scheduler.rs index 81d5e7be8..f575bbd4b 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -198,8 +198,8 @@ async fn fetch_idle(ctx: &Context, connection: &mut Imap, folder_config: Config) .await .context("prepare IMAP connection") { - connection.trigger_reconnect(ctx); warn!(ctx, "{:#}", err); + connection.trigger_reconnect(ctx); return connection.fake_idle(ctx, Some(watch_folder)).await; } From 468356b12040d6078dcfab078c674883ee4591a8 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 3 Jan 2023 12:08:45 +0000 Subject: [PATCH 31/39] Trigger reconnection when failing to fetch existing messages --- CHANGELOG.md | 1 + src/scheduler.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 476504be4..2cbcc49ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Do not strip leading spaces from message lines #3867 - Fix uncaught exception in JSON-RPC tests #3884 - Fix STARTTLS connection and add a test for it #3907 +- Trigger reconnection when failing to fetch existing messages #3911 ## 1.104.0 diff --git a/src/scheduler.rs b/src/scheduler.rs index f575bbd4b..d3d3bca2c 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -143,6 +143,7 @@ async fn inbox_loop(ctx: Context, started: Sender<()>, inbox_handlers: ImapConne if !fetched_existing_msgs { if let Err(err) = connection.fetch_existing_msgs(&ctx).await { warn!(ctx, "Failed to fetch existing messages: {:#}", err); + connection.trigger_reconnect(&ctx); } } } From ac15b3a5af5ae34eca92e39c9f555bf9516eb0c0 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 3 Jan 2023 01:19:57 +0000 Subject: [PATCH 32/39] Remove `rust-toolchain` file Any Rust toolchain above MSRV should be usable. --- rust-toolchain | 1 - 1 file changed, 1 deletion(-) delete mode 100644 rust-toolchain diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index 940573042..000000000 --- a/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.64.0 From c9ab9d59c2b8200efa18c94b9c26053616d45355 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 3 Jan 2023 13:54:23 +0000 Subject: [PATCH 33/39] Adapt the comment, there is no more `rust-toolchain` --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b57e5b06..ee4abe96c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,7 +69,7 @@ jobs: strategy: matrix: include: - # Currently used Rust version, same as in `rust-toolchain` file. + # Currently used Rust version. - os: ubuntu-latest rust: 1.64.0 python: 3.9 From 5b1278458991d1c38733d17b2319d42fd81c110f Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 3 Jan 2023 15:45:08 +0000 Subject: [PATCH 34/39] ci: update rust toolchain for repl.exe builds --- .github/workflows/repl.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/repl.yml b/.github/workflows/repl.yml index 38b84e921..c0a76fc37 100644 --- a/.github/workflows/repl.yml +++ b/.github/workflows/repl.yml @@ -16,7 +16,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.50.0 + toolchain: 1.66.0 override: true - name: build From 138e62e1ef95ae1a4b079d19b07b8f68ed0848c7 Mon Sep 17 00:00:00 2001 From: link2xt Date: Tue, 3 Jan 2023 18:52:34 +0000 Subject: [PATCH 35/39] Improve error handling of existing messages fetch and never retry There are at least two user reports that fetching existing messages sometimes results in infinite loop of retrying it. Account is working if set up from the backup, but never starts working if set up from scratch. This change improves error reporting, but also sets FetchedExistingMsgs before actually trying to do it. This way if the operation fails, connection is reestablished, but fetching existing messages is not retried again over and over. --- CHANGELOG.md | 1 + src/imap.rs | 112 ++++++++++++++++++++++++++++------------------- src/scheduler.rs | 10 +++++ 3 files changed, 77 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cbcc49ad..323cfac6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Fix uncaught exception in JSON-RPC tests #3884 - Fix STARTTLS connection and add a test for it #3907 - Trigger reconnection when failing to fetch existing messages #3911 +- Do not retry fetching existing messages after failure, prevents infinite reconnection loop #3913 ## 1.104.0 diff --git a/src/imap.rs b/src/imap.rs index 2df278f29..cb3843ee0 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -677,7 +677,10 @@ impl Imap { return Ok(false); } - let new_emails = self.select_with_uidvalidity(context, folder).await?; + let new_emails = self + .select_with_uidvalidity(context, folder) + .await + .with_context(|| format!("failed to select folder {}", folder))?; if !new_emails && !fetch_existing_msgs { info!(context, "No new emails in folder {}", folder); @@ -837,9 +840,15 @@ impl Imap { } self.prepare(context).await.context("could not connect")?; - add_all_recipients_as_contacts(context, self, Config::ConfiguredSentboxFolder).await; - add_all_recipients_as_contacts(context, self, Config::ConfiguredMvboxFolder).await; - add_all_recipients_as_contacts(context, self, Config::ConfiguredInboxFolder).await; + add_all_recipients_as_contacts(context, self, Config::ConfiguredSentboxFolder) + .await + .context("failed to get recipients from the sentbox")?; + add_all_recipients_as_contacts(context, self, Config::ConfiguredMvboxFolder) + .await + .context("failed to ge recipients from the movebox")?; + add_all_recipients_as_contacts(context, self, Config::ConfiguredInboxFolder) + .await + .context("failed to get recipients from the inbox")?; if context.get_config_bool(Config::FetchExistingMsgs).await? { for config in &[ @@ -848,6 +857,10 @@ impl Imap { Config::ConfiguredSentboxFolder, ] { if let Some(folder) = context.get_config(*config).await? { + info!( + context, + "Fetching existing messages from folder \"{}\"", folder + ); self.fetch_new_messages(context, &folder, false, true) .await .context("could not fetch existing messages")?; @@ -856,9 +869,6 @@ impl Imap { } info!(context, "Done fetching existing messages."); - context - .set_config_bool(Config::FetchedExistingMsgs, true) - .await?; Ok(()) } } @@ -1207,8 +1217,10 @@ impl Imap { /// Prefetch all messages greater than or equal to `uid_next`. Returns a list of fetch results /// in the order of ascending delivery time to the server (INTERNALDATE). async fn prefetch(&mut self, uid_next: u32) -> Result> { - let session = self.session.as_mut(); - let session = session.context("fetch_after(): IMAP No Connection established")?; + let session = self + .session + .as_mut() + .context("no IMAP connection established")?; // fetch messages with larger UID than the last one seen let set = format!("{}:*", uid_next); @@ -1233,7 +1245,6 @@ impl Imap { } } } - drop(list); Ok(msgs.into_iter().map(|((_, uid), msg)| (uid, msg)).collect()) } @@ -2306,49 +2317,58 @@ impl std::fmt::Display for UidRange { } } } -async fn add_all_recipients_as_contacts(context: &Context, imap: &mut Imap, folder: Config) { - let mailbox = if let Ok(Some(m)) = context.get_config(folder).await { +async fn add_all_recipients_as_contacts( + context: &Context, + imap: &mut Imap, + folder: Config, +) -> Result<()> { + let mailbox = if let Some(m) = context.get_config(folder).await? { m } else { - return; + info!( + context, + "Folder {} is not configured, skipping fetching contacts from it.", folder + ); + return Ok(()); }; - if let Err(e) = imap.select_with_uidvalidity(context, &mailbox).await { - // We are using Anyhow's .context() and to show the inner error, too, we need the {:#}: - warn!(context, "Could not select {}: {:#}", mailbox, e); - return; - } - match imap.get_all_recipients(context).await { - Ok(contacts) => { - let mut any_modified = false; - for contact in contacts { - let display_name_normalized = contact - .display_name - .as_ref() - .map(|s| normalize_name(s)) - .unwrap_or_default(); + imap.select_with_uidvalidity(context, &mailbox) + .await + .with_context(|| format!("could not select {}", mailbox))?; - match Contact::add_or_lookup( - context, - &display_name_normalized, - &contact.addr, - Origin::OutgoingTo, - ) - .await - { - Ok((_, modified)) => { - if modified != Modifier::None { - any_modified = true; - } - } - Err(e) => warn!(context, "Could not add recipient: {}", e), + let contacts = imap + .get_all_recipients(context) + .await + .context("could not get recipients")?; + + let mut any_modified = false; + for contact in contacts { + let display_name_normalized = contact + .display_name + .as_ref() + .map(|s| normalize_name(s)) + .unwrap_or_default(); + + match Contact::add_or_lookup( + context, + &display_name_normalized, + &contact.addr, + Origin::OutgoingTo, + ) + .await + { + Ok((_, modified)) => { + if modified != Modifier::None { + any_modified = true; } } - if any_modified { - context.emit_event(EventType::ContactsChanged(None)); - } + Err(e) => warn!(context, "Could not add recipient: {}", e), } - Err(e) => warn!(context, "Could not add recipients: {}", e), - }; + } + if any_modified { + context.emit_event(EventType::ContactsChanged(None)); + } + + Ok(()) } #[cfg(test)] diff --git a/src/scheduler.rs b/src/scheduler.rs index d3d3bca2c..92e569010 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -141,6 +141,16 @@ async fn inbox_loop(ctx: Context, started: Sender<()>, inbox_handlers: ImapConne match ctx.get_config_bool(Config::FetchedExistingMsgs).await { Ok(fetched_existing_msgs) => { if !fetched_existing_msgs { + // Consider it done even if we fail. + // + // This operation is not critical enough to retry, + // especially if the error is persistent. + if let Err(err) = + ctx.set_config_bool(Config::FetchedExistingMsgs, true).await + { + warn!(ctx, "Can't set Config::FetchedExistingMsgs: {:#}", err); + } + if let Err(err) = connection.fetch_existing_msgs(&ctx).await { warn!(ctx, "Failed to fetch existing messages: {:#}", err); connection.trigger_reconnect(&ctx); From 37a212ddc49ff94167f7309fb2553e9903c8269a Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 4 Jan 2023 13:35:11 +0000 Subject: [PATCH 36/39] ci: remove failing actions-rs/toolchain calls It fails because there is no `rust-toolchain` file anymore. ubuntu-latest already has cargo installed, there is no need to reintall it. --- .github/workflows/upload-docs.yml | 1 - .github/workflows/upload-ffi-docs.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/upload-docs.yml b/.github/workflows/upload-docs.yml index fa9b7f6e4..c624cb081 100644 --- a/.github/workflows/upload-docs.yml +++ b/.github/workflows/upload-docs.yml @@ -13,7 +13,6 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - name: Build the documentation with cargo run: | cargo doc --package deltachat --no-deps diff --git a/.github/workflows/upload-ffi-docs.yml b/.github/workflows/upload-ffi-docs.yml index 96c192803..73fa07cb1 100644 --- a/.github/workflows/upload-ffi-docs.yml +++ b/.github/workflows/upload-ffi-docs.yml @@ -13,7 +13,6 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - name: Build the documentation with cargo run: | cargo doc --package deltachat_ffi --no-deps From 1f420777af077f5635ffd2e7c3c28c7dc911b179 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 14:38:48 +0000 Subject: [PATCH 37/39] cargo: bump once_cell from 1.16.0 to 1.17.0 Bumps [once_cell](https://github.com/matklad/once_cell) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/matklad/once_cell/releases) - [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md) - [Commits](https://github.com/matklad/once_cell/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: once_cell dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- deltachat-ffi/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff69d5210..14e347901 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2355,9 +2355,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "oorandom" diff --git a/Cargo.toml b/Cargo.toml index 1c9d7230e..4cfd9d809 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ native-tls = "0.2" num_cpus = "1.15" num-derive = "0.3" num-traits = "0.2" -once_cell = "1.16.0" +once_cell = "1.17.0" percent-encoding = "2.2" pgp = { version = "0.9", default-features = false } pretty_env_logger = { version = "0.4", optional = true } diff --git a/deltachat-ffi/Cargo.toml b/deltachat-ffi/Cargo.toml index e7cc70998..b6e18901b 100644 --- a/deltachat-ffi/Cargo.toml +++ b/deltachat-ffi/Cargo.toml @@ -24,7 +24,7 @@ tokio = { version = "1", features = ["rt-multi-thread"] } anyhow = "1" thiserror = "1" rand = "0.7" -once_cell = "1.16.0" +once_cell = "1.17.0" [features] default = ["vendored"] From 8ac7f639d8d32a40626a7edb30c957736a40cb95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 23:50:21 +0000 Subject: [PATCH 38/39] cargo: bump toml from 0.5.9 to 0.5.10 Bumps [toml](https://github.com/toml-rs/toml) from 0.5.9 to 0.5.10. - [Release notes](https://github.com/toml-rs/toml/releases) - [Commits](https://github.com/toml-rs/toml/commits/toml-v0.5.10) --- updated-dependencies: - dependency-name: toml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14e347901..373223d0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3641,9 +3641,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" dependencies = [ "serde", ] From c5d18023463460316395fdb68a910cd5b31cc1d8 Mon Sep 17 00:00:00 2001 From: bjoern Date: Thu, 5 Jan 2023 10:31:47 +0100 Subject: [PATCH 39/39] "archive" consistency and improvements (#3918) * move 'archived link' betweeen pinned and normal cahts or above normal chats * add icon for 'archived chats' link * let get_fresh_msg_cnt() work for DC_CHAT_ID_ARCHIVED_LINK * move 'archived link' topmost * use less noticeable archived-icon * slightly smaller archived icon * update CHANGELOG --- CHANGELOG.md | 2 ++ assets/icon-archive.png | Bin 0 -> 1652 bytes assets/icon-archive.svg | 60 ++++++++++++++++++++++++++++++++++++++ deltachat-ffi/deltachat.h | 6 +++- src/chat.rs | 51 +++++++++++++++++++++++++++----- src/chatlist.rs | 20 +++++-------- 6 files changed, 118 insertions(+), 21 deletions(-) create mode 100644 assets/icon-archive.png create mode 100644 assets/icon-archive.svg diff --git a/CHANGELOG.md b/CHANGELOG.md index 323cfac6a..1ea187ef2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - Add fuzzing tests #3853 - Add mappings for some file types to Viewtype / MIME type #3881 - Buffer IMAP client writes #3888 +- move `DC_CHAT_ID_ARCHIVED_LINK` to the top of chat lists + and make `dc_get_fresh_msg_cnt()` work for `DC_CHAT_ID_ARCHIVED_LINK` #3918 ### API-Changes - jsonrpc: add python API for webxdc updates #3872 diff --git a/assets/icon-archive.png b/assets/icon-archive.png new file mode 100644 index 0000000000000000000000000000000000000000..95d35e2a5107e14ee900d0b7947b2eb9a38e6a85 GIT binary patch literal 1652 zcmd^ATTI$_6#ikYc*lf9ywywG>Pu%?Y;CKExLGC(>n@h9#T$y^EKHo(YAY(MHFIez zOu~pNxLod^s zvwSgIq9bF_%>Jbz68a|by7K3QiqpfSq$_ueiSe`Fyc-t-pNl$ruwv#er;|rOAaAem zT9olDSg+*dm&UM?Ml`J>!(Te_s6#<1usqHV@2+5L%kxZf9$6+ug0VypMh5W$K)@n+ zG#{Y!1(ySWFBJYf+o5HpI@jjJA9zx2@y=hvX-M(h#wqFaWDo2R8c!X|>Lr0C;?-A3(cn9ul7IZ09IOhH6=T}%l zV!zfbI8w?V?v}wPx?r=}+-`6hrR#z~M1-chBe`Iw6i(=34doBdmlFp5)2ZAM9}?tt zZO7!A8iJ_IOdTtAoyvUMX2@hoTpZY8Bbi(+ngyBMu4c&Q^#-TXwuKoNe)OgZo<62611wKQ842J5wsXpzW($r{M;VFWLe<)XcDs1P zJM~Hqo2_j{z68?K>TR$J8m3T0{EQ%v^&&;T&=ZnwR%gY{lt{OWDX#4izTMEYNUgUB z;u?k^JYK4_E%Koa`5hrFUp^;sZF+E4lY{G4O@-hy9B!&9X*Nouk5zI93VZonMZax=i}#3_4}X#E|2Lf<^LgvH5~-kH)A*>qNdgHY zpY++OOtHb4XK^fbbI7fLtd6^6Vh1-&8=PW_)dKCzO^-8h0|0$5KeZCs|Wh z2;+}mO#oNkx-+&Dz3UMvE?WLt)p2lbnrGHWboC7)h?S2Zkx054 zP|AY9?|YdrYTnW9BMX@6SVV;3Q#uM;++!T|rPU3JH{80{$jHc|?7g?WCnmj)$i0asOjd;z5uQ8K@SaufNoUd8ti3fdUJcqYPtKO^YH3!Z;Q at}{@Dw+Qr~*o5AX0Z1oLW%s;ByZkq}L1Whd literal 0 HcmV?d00001 diff --git a/assets/icon-archive.svg b/assets/icon-archive.svg new file mode 100644 index 000000000..a8ba45d49 --- /dev/null +++ b/assets/icon-archive.svg @@ -0,0 +1,60 @@ + + + + + + + + + + diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 4a03f1a8f..47452f6ac 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -1227,7 +1227,11 @@ int dc_get_msg_cnt (dc_context_t* context, uint32_t ch * Get the number of _fresh_ messages in a chat. * Typically used to implement a badge with a number in the chatlist. * - * If the specified chat is muted, + * As muted archived chats are not unarchived automatically, + * a similar information is needed for the @ref dc_get_chatlist() "archive link" as well: + * here, the number of archived chats containing fresh messages is returned. + * + * If the specified chat is muted or the @ref dc_get_chatlist() "archive link", * the UI should show the badge counter "less obtrusive", * e.g. using "gray" instead of "red" color. * diff --git a/src/chat.rs b/src/chat.rs index 8be73e1ef..4de92e070 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -782,17 +782,35 @@ impl ChatId { // the times are average, no matter if there are fresh messages or not - // and have to be multiplied by the number of items shown at once on the chatlist, // so savings up to 2 seconds are possible on older devices - newer ones will feel "snappier" :) - let count = context - .sql - .count( - "SELECT COUNT(*) + let count = if self.is_archived_link() { + context + .sql + .count( + "SELECT COUNT(DISTINCT(m.chat_id)) + FROM msgs m + LEFT JOIN chats c ON m.chat_id=c.id + WHERE m.state=10 + and m.hidden=0 + AND m.chat_id>9 + AND c.blocked=0 + AND c.archived=1 + ", + paramsv![], + ) + .await? + } else { + context + .sql + .count( + "SELECT COUNT(*) FROM msgs WHERE state=? AND hidden=0 AND chat_id=?;", - paramsv![MessageState::InFresh, self], - ) - .await?; + paramsv![MessageState::InFresh, self], + ) + .await? + }; Ok(count) } @@ -1216,6 +1234,10 @@ impl Chat { if !image_rel.is_empty() { return Ok(Some(get_abs_path(context, image_rel))); } + } else if self.id.is_archived_link() { + if let Ok(image_rel) = get_archive_icon(context).await { + return Ok(Some(get_abs_path(context, image_rel))); + } } else if self.typ == Chattype::Single { let contacts = get_chat_contacts(context, self.id).await?; if let Some(contact_id) = contacts.first() { @@ -1708,6 +1730,21 @@ pub(crate) async fn get_broadcast_icon(context: &Context) -> Result { Ok(icon) } +pub(crate) async fn get_archive_icon(context: &Context) -> Result { + if let Some(icon) = context.sql.get_raw_config("icon-archive").await? { + return Ok(icon); + } + + let icon = include_bytes!("../assets/icon-archive.png"); + let blob = BlobObject::create(context, "icon-archive.png", icon).await?; + let icon = blob.as_name().to_string(); + context + .sql + .set_raw_config("icon-archive", Some(&icon)) + .await?; + Ok(icon) +} + async fn update_special_chat_name( context: &Context, contact_id: ContactId, diff --git a/src/chatlist.rs b/src/chatlist.rs index da7d309a4..df80b15e2 100644 --- a/src/chatlist.rs +++ b/src/chatlist.rs @@ -92,8 +92,6 @@ impl Chatlist { let flag_no_specials = 0 != listflags & DC_GCL_NO_SPECIALS; let flag_add_alldone_hint = 0 != listflags & DC_GCL_ADD_ALLDONE_HINT; - let mut add_archived_link_item = false; - let process_row = |row: &rusqlite::Row| { let chat_id: ChatId = row.get(0)?; let msg_id: Option = row.get(1)?; @@ -123,7 +121,7 @@ impl Chatlist { // // The query shows messages from blocked contacts in // groups. Otherwise it would be hard to follow conversations. - let mut ids = if let Some(query_contact_id) = query_contact_id { + let ids = if let Some(query_contact_id) = query_contact_id { // show chats shared with a given contact context.sql.query_map( "SELECT c.id, m.id @@ -216,7 +214,7 @@ impl Chatlist { } else { ChatId::new(0) }; - let ids = context.sql.query_map( + let mut ids = context.sql.query_map( "SELECT c.id, m.id FROM chats c LEFT JOIN msgs m @@ -236,19 +234,15 @@ impl Chatlist { process_row, process_rows, ).await?; - if !flag_no_specials { - add_archived_link_item = true; + if !flag_no_specials && get_archived_cnt(context).await? > 0 { + if ids.is_empty() && flag_add_alldone_hint { + ids.push((DC_CHAT_ID_ALLDONE_HINT, None)); + } + ids.insert(0, (DC_CHAT_ID_ARCHIVED_LINK, None)); } ids }; - if add_archived_link_item && get_archived_cnt(context).await? > 0 { - if ids.is_empty() && flag_add_alldone_hint { - ids.push((DC_CHAT_ID_ALLDONE_HINT, None)); - } - ids.push((DC_CHAT_ID_ARCHIVED_LINK, None)); - } - Ok(Chatlist { ids }) }