From 7a6283978f6467de52fe3986597ac025e6df2d2a Mon Sep 17 00:00:00 2001 From: link2xt Date: Sat, 16 Nov 2024 19:00:40 +0000 Subject: [PATCH 01/14] refactor: remove slicing from `is_file_in_use` There is a change in behavior for the case when name is the same as the suffix (`name_len` == `namespc_len`), but normally `files_in_use` should not contain empty filenames. --- src/sql.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/sql.rs b/src/sql.rs index 0356f851c6..3b6f2e4e92 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -942,15 +942,12 @@ pub async fn remove_unused_files(context: &Context) -> Result<()> { Ok(()) } -#[allow(clippy::indexing_slicing)] fn is_file_in_use(files_in_use: &HashSet, namespc_opt: Option<&str>, name: &str) -> bool { let name_to_check = if let Some(namespc) = namespc_opt { - let name_len = name.len(); - let namespc_len = namespc.len(); - if name_len <= namespc_len || !name.ends_with(namespc) { + let Some(name) = name.strip_suffix(namespc) else { return false; - } - &name[..name_len - namespc_len] + }; + name } else { name }; From 6668d408c52007616a552c524be4cbe352584063 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 11:16:35 +0000 Subject: [PATCH 02/14] refactor: remove unnecessary `allow(clippy::indexing_slicing)` clippy::indexing_slicing is already allowed in test builds. --- src/authres.rs | 1 - src/configure.rs | 2 -- src/configure/auto_mozilla.rs | 2 -- src/configure/auto_outlook.rs | 2 -- src/location.rs | 2 -- src/mimefactory.rs | 1 - src/mimeparser.rs | 2 -- src/provider.rs | 2 -- src/test_utils.rs | 1 - src/tests/aeap.rs | 2 -- src/tools.rs | 2 -- 11 files changed, 19 deletions(-) diff --git a/src/authres.rs b/src/authres.rs index 4d6e86d83f..84504d1ee2 100644 --- a/src/authres.rs +++ b/src/authres.rs @@ -260,7 +260,6 @@ fn parse_authservid_candidates_config(config: &Option) -> BTreeSet<&str> #[cfg(test)] mod tests { - #![allow(clippy::indexing_slicing)] use tokio::fs; use tokio::io::AsyncReadExt; diff --git a/src/configure.rs b/src/configure.rs index 990501468e..c317f6819a 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -611,8 +611,6 @@ pub enum Error { #[cfg(test)] mod tests { - #![allow(clippy::indexing_slicing)] - use super::*; use crate::config::Config; use crate::login_param::EnteredServerLoginParam; diff --git a/src/configure/auto_mozilla.rs b/src/configure/auto_mozilla.rs index 4560bf52d8..1e007e9018 100644 --- a/src/configure/auto_mozilla.rs +++ b/src/configure/auto_mozilla.rs @@ -272,8 +272,6 @@ pub(crate) async fn moz_autoconfigure( #[cfg(test)] mod tests { - #![allow(clippy::indexing_slicing)] - use super::*; #[test] diff --git a/src/configure/auto_outlook.rs b/src/configure/auto_outlook.rs index a3fef6f322..533305ebae 100644 --- a/src/configure/auto_outlook.rs +++ b/src/configure/auto_outlook.rs @@ -215,8 +215,6 @@ pub(crate) async fn outlk_autodiscover( #[cfg(test)] mod tests { - #![allow(clippy::indexing_slicing)] - use super::*; #[test] diff --git a/src/location.rs b/src/location.rs index f2fa919b83..5dcc9a258b 100644 --- a/src/location.rs +++ b/src/location.rs @@ -880,8 +880,6 @@ async fn maybe_send_locations(context: &Context) -> Result> { #[cfg(test)] mod tests { - #![allow(clippy::indexing_slicing)] - use super::*; use crate::config::Config; use crate::message::MessageState; diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 83556c0d01..fb294b107d 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -2274,7 +2274,6 @@ mod tests { let msg = message.as_string(); let header_end = msg.find("Hi").unwrap(); - #[allow(clippy::indexing_slicing)] let headers = msg[0..header_end].trim(); assert!(!headers.lines().any(|l| l.trim().is_empty())); diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 095d4e12fb..ac493514bf 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -2362,8 +2362,6 @@ async fn ndn_maybe_add_info_msg( #[cfg(test)] mod tests { - #![allow(clippy::indexing_slicing)] - use mailparse::ParsedMail; use super::*; diff --git a/src/provider.rs b/src/provider.rs index a909d3ead6..78aade13c6 100644 --- a/src/provider.rs +++ b/src/provider.rs @@ -288,8 +288,6 @@ pub fn get_provider_by_id(id: &str) -> Option<&'static Provider> { #[cfg(test)] mod tests { - #![allow(clippy::indexing_slicing)] - use super::*; use crate::test_utils::TestContext; diff --git a/src/test_utils.rs b/src/test_utils.rs index 4a8473bc05..85d232ded1 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -1,7 +1,6 @@ //! Utilities to help writing tests. //! //! This private module is only compiled for test runs. -#![allow(clippy::indexing_slicing)] use std::collections::{BTreeMap, HashSet}; use std::fmt::Write; use std::ops::{Deref, DerefMut}; diff --git a/src/tests/aeap.rs b/src/tests/aeap.rs index b2b599e0ec..18ea10041c 100644 --- a/src/tests/aeap.rs +++ b/src/tests/aeap.rs @@ -1,5 +1,3 @@ -#![allow(clippy::indexing_slicing)] - use anyhow::Result; use crate::chat; diff --git a/src/tools.rs b/src/tools.rs index 89c50759d1..f4a72fec0c 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -709,8 +709,6 @@ pub(crate) fn inc_and_check( #[cfg(test)] mod tests { - #![allow(clippy::indexing_slicing)] - use chrono::NaiveDate; use proptest::prelude::*; From ea1dfafa139d89b53a5e02379e8e6c65bed91f44 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 13:07:01 +0000 Subject: [PATCH 03/14] refactor: don't use slicing in `remove_nonstandard_footer` --- src/simplify.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/simplify.rs b/src/simplify.rs index 1d714a6b8f..86dbd3cdea 100644 --- a/src/simplify.rs +++ b/src/simplify.rs @@ -53,7 +53,6 @@ pub(crate) fn remove_message_footer<'a>( /// Returns `(lines, is_footer_removed)` tuple; /// `is_footer_removed` is set to `true` if the footer was actually removed from `lines` /// (which is equal to the input array otherwise). -#[allow(clippy::indexing_slicing)] fn remove_nonstandard_footer<'a>(lines: &'a [&str]) -> (&'a [&'a str], bool) { for (ix, &line) in lines.iter().enumerate() { if line == "--" @@ -63,7 +62,10 @@ fn remove_nonstandard_footer<'a>(lines: &'a [&str]) -> (&'a [&'a str], bool) { || line.starts_with("*****") || line.starts_with("~~~~~") { - return (&lines[..ix], true); + // `get` should always return `Some` here. + if let Some(lines) = lines.get(..ix) { + return (lines, true); + } } } (lines, false) From a2ebfc1c591741ca9003a5e487ea8bc76ea8f548 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 11:15:58 +0000 Subject: [PATCH 04/14] refactor: do not use slicing in `qr` module --- src/qr.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/qr.rs b/src/qr.rs index 23baaf3c9b..30f0eb4e69 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -367,9 +367,10 @@ pub fn format_backup(qr: &Qr) -> Result { /// scheme: `OPENPGP4FPR:FINGERPRINT#a=ADDR&n=NAME&i=INVITENUMBER&s=AUTH` /// or: `OPENPGP4FPR:FINGERPRINT#a=ADDR&g=GROUPNAME&x=GROUPID&i=INVITENUMBER&s=AUTH` /// or: `OPENPGP4FPR:FINGERPRINT#a=ADDR` -#[allow(clippy::indexing_slicing)] async fn decode_openpgp(context: &Context, qr: &str) -> Result { - let payload = &qr[OPENPGP4FPR_SCHEME.len()..]; + let payload = qr + .get(OPENPGP4FPR_SCHEME.len()..) + .context("Invalid OPENPGP4FPR scheme")?; // macOS and iOS sometimes replace the # with %23 (uri encode it), we should be able to parse this wrong format too. // see issue https://github.com/deltachat/deltachat-core-rust/issues/1969 for more info @@ -546,7 +547,7 @@ async fn decode_ideltachat(context: &Context, prefix: &str, qr: &str) -> Result< fn decode_account(qr: &str) -> Result { let payload = qr .get(DCACCOUNT_SCHEME.len()..) - .context("invalid DCACCOUNT payload")?; + .context("Invalid DCACCOUNT payload")?; let url = url::Url::parse(payload).context("Invalid account URL")?; if url.scheme() == "http" || url.scheme() == "https" { Ok(Qr::Account { @@ -564,7 +565,7 @@ fn decode_account(qr: &str) -> Result { fn decode_webrtc_instance(_context: &Context, qr: &str) -> Result { let payload = qr .get(DCWEBRTC_SCHEME.len()..) - .context("invalid DCWEBRTC payload")?; + .context("Invalid DCWEBRTC payload")?; let (_type, url) = Message::parse_webrtc_instance(payload); let url = url::Url::parse(&url).context("Invalid WebRTC instance")?; @@ -637,7 +638,7 @@ fn decode_shadowsocks_proxy(qr: &str) -> Result { fn decode_backup2(qr: &str) -> Result { let payload = qr .strip_prefix(DCBACKUP2_SCHEME) - .ok_or_else(|| anyhow!("invalid DCBACKUP scheme"))?; + .ok_or_else(|| anyhow!("Invalid DCBACKUP2 scheme"))?; let (auth_token, node_addr) = payload .split_once('&') .context("Backup QR code has no separator")?; @@ -668,9 +669,10 @@ struct CreateAccountErrorResponse { /// take a qr of the type DC_QR_ACCOUNT, parse it's parameters, /// download additional information from the contained url and set the parameters. /// on success, a configure::configure() should be able to log in to the account -#[allow(clippy::indexing_slicing)] async fn set_account_from_qr(context: &Context, qr: &str) -> Result<()> { - let url_str = &qr[DCACCOUNT_SCHEME.len()..]; + let url_str = qr + .get(DCACCOUNT_SCHEME.len()..) + .context("Invalid DCACCOUNT scheme")?; if !url_str.starts_with(HTTPS_SCHEME) { bail!("DCACCOUNT QR codes must use HTTPS scheme"); @@ -800,9 +802,10 @@ pub async fn set_config_from_qr(context: &Context, qr: &str) -> Result<()> { /// Extract address for the mailto scheme. /// /// Scheme: `mailto:addr...?subject=...&body=..` -#[allow(clippy::indexing_slicing)] async fn decode_mailto(context: &Context, qr: &str) -> Result { - let payload = &qr[MAILTO_SCHEME.len()..]; + let payload = qr + .get(MAILTO_SCHEME.len()..) + .context("Invalid mailto: scheme")?; let (addr, query) = if let Some(query_index) = payload.find('?') { (&payload[..query_index], &payload[query_index + 1..]) @@ -855,9 +858,8 @@ async fn decode_mailto(context: &Context, qr: &str) -> Result { /// Extract address for the smtp scheme. /// /// Scheme: `SMTP:addr...:subject...:body...` -#[allow(clippy::indexing_slicing)] async fn decode_smtp(context: &Context, qr: &str) -> Result { - let payload = &qr[SMTP_SCHEME.len()..]; + let payload = qr.get(SMTP_SCHEME.len()..).context("Invalid SMTP scheme")?; let addr = if let Some(query_index) = payload.find(':') { &payload[..query_index] @@ -875,14 +877,13 @@ async fn decode_smtp(context: &Context, qr: &str) -> Result { /// Scheme: `MATMSG:TO:addr...;SUB:subject...;BODY:body...;` /// /// There may or may not be linebreaks after the fields. -#[allow(clippy::indexing_slicing)] async fn decode_matmsg(context: &Context, qr: &str) -> Result { // Does not work when the text `TO:` is used in subject/body _and_ TO: is not the first field. // we ignore this case. let addr = if let Some(to_index) = qr.find("TO:") { - let addr = qr[to_index + 3..].trim(); + let addr = qr.get(to_index + 3..).unwrap_or_default().trim(); if let Some(semi_index) = addr.find(';') { - addr[..semi_index].trim() + addr.get(..semi_index).unwrap_or_default().trim() } else { addr } @@ -903,7 +904,6 @@ static VCARD_EMAIL_RE: Lazy = /// Extract address for the vcard scheme. /// /// Scheme: `VCARD:BEGIN\nN:last name;first name;...;\nEMAIL;:addr...;` -#[allow(clippy::indexing_slicing)] async fn decode_vcard(context: &Context, qr: &str) -> Result { let name = VCARD_NAME_RE .captures(qr) @@ -915,8 +915,8 @@ async fn decode_vcard(context: &Context, qr: &str) -> Result { }) .unwrap_or_default(); - let addr = if let Some(caps) = VCARD_EMAIL_RE.captures(qr) { - normalize_address(caps[2].trim())? + let addr = if let Some(cap) = VCARD_EMAIL_RE.captures(qr).and_then(|caps| caps.get(2)) { + normalize_address(cap.as_str().trim())? } else { bail!("Bad e-mail address"); }; From a264cbf1f06298f320b385b3b2c1c0f1e11c8ed6 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 13:20:01 +0000 Subject: [PATCH 05/14] refactor: eliminate indexing in `compute_mailinglist_name` --- src/receive_imf.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/receive_imf.rs b/src/receive_imf.rs index e4bbeac892..2ad2a714d5 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -2465,14 +2465,16 @@ async fn create_or_lookup_mailinglist( } } -#[allow(clippy::indexing_slicing)] fn compute_mailinglist_name( list_id_header: &str, listid: &str, mime_parser: &MimeMessage, ) -> String { - let mut name = match LIST_ID_REGEX.captures(list_id_header) { - Some(cap) => cap[1].trim().to_string(), + let mut name = match LIST_ID_REGEX + .captures(list_id_header) + .and_then(|caps| caps.get(1)) + { + Some(cap) => cap.as_str().trim().to_string(), None => "".to_string(), }; @@ -2519,8 +2521,11 @@ fn compute_mailinglist_name( // 51231231231231231231231232869f58.xing.com -> xing.com static PREFIX_32_CHARS_HEX: Lazy = Lazy::new(|| Regex::new(r"([0-9a-fA-F]{32})\.(.{6,})").unwrap()); - if let Some(cap) = PREFIX_32_CHARS_HEX.captures(listid) { - name = cap[2].to_string(); + if let Some(cap) = PREFIX_32_CHARS_HEX + .captures(listid) + .and_then(|caps| caps.get(2)) + { + name = cap.as_str().to_string(); } else { name = listid.to_string(); } From 6f6ad04325d44b07e2c39bcd22e7be0750d886ed Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 16:47:30 +0000 Subject: [PATCH 06/14] refactor: remove unused `allow(clippy::indexing_slicing)` --- src/securejoin.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/securejoin.rs b/src/securejoin.rs index 7118c8db28..863d2b4f2f 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -279,7 +279,6 @@ pub(crate) enum HandshakeMessage { /// /// When `handle_securejoin_handshake()` is called, the message is not yet filed in the /// database; this is done by `receive_imf()` later on as needed. -#[allow(clippy::indexing_slicing)] pub(crate) async fn handle_securejoin_handshake( context: &Context, mime_message: &MimeMessage, From ce02f2aab20efff7f368396bc8f41f351e870da6 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 17:15:07 +0000 Subject: [PATCH 07/14] refactor: remove indexing/slicing from `remove_message_footer` --- src/simplify.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/simplify.rs b/src/simplify.rs index 86dbd3cdea..b1b2171526 100644 --- a/src/simplify.rs +++ b/src/simplify.rs @@ -1,4 +1,5 @@ //! # Simplify incoming plaintext. +use crate::tools::IsNoneOrEmpty; /// Protects lines starting with `--` against being treated as a footer. /// for that, we insert a ZERO WIDTH SPACE (ZWSP, 0x200B); @@ -20,7 +21,6 @@ pub fn escape_message_footer_marks(text: &str) -> String { /// Returns `(lines, footer_lines)` tuple; /// `footer_lines` is set to `Some` if the footer was actually removed from `lines` /// (which is equal to the input array otherwise). -#[allow(clippy::indexing_slicing)] pub(crate) fn remove_message_footer<'a>( lines: &'a [&str], ) -> (&'a [&'a str], Option<&'a [&'a str]>) { @@ -28,14 +28,13 @@ pub(crate) fn remove_message_footer<'a>( for (ix, &line) in lines.iter().enumerate() { match line { // some providers encode `-- ` to `-- =20` which results in `-- ` - "-- " | "-- " => return (&lines[..ix], lines.get(ix + 1..)), + "-- " | "-- " => return (lines.get(..ix).unwrap_or(lines), lines.get(ix + 1..)), // some providers encode `-- ` to `=2D-` which results in only `--`; // use that only when no other footer is found // and if the line before is empty and the line after is not empty "--" => { - if (ix == 0 || lines[ix - 1].is_empty()) - && ix != lines.len() - 1 - && !lines[ix + 1].is_empty() + if (ix == 0 || lines.get(ix.saturating_sub(1)).is_none_or_empty()) + && !lines.get(ix + 1).is_none_or_empty() { nearly_standard_footer = Some(ix); } @@ -44,7 +43,7 @@ pub(crate) fn remove_message_footer<'a>( } } if let Some(ix) = nearly_standard_footer { - return (&lines[..ix], lines.get(ix + 1..)); + return (lines.get(..ix).unwrap_or(lines), lines.get(ix + 1..)); } (lines, None) } From 0cdd9b4fa9e216d966a4446e286369761aa6fd58 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 18:22:14 +0000 Subject: [PATCH 08/14] refactor: remove indexing/slicing from `squash_attachment_parts` --- src/mimeparser.rs | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/mimeparser.rs b/src/mimeparser.rs index ac493514bf..4218ea6d74 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -665,11 +665,13 @@ impl MimeMessage { /// Delta Chat sends attachments, such as images, in two-part messages, with the first message /// containing a description. If such a message is detected, text from the first part can be /// moved to the second part, and the first part dropped. - #[allow(clippy::indexing_slicing)] fn squash_attachment_parts(&mut self) { - if let [textpart, filepart] = &self.parts[..] { - let need_drop = textpart.typ == Viewtype::Text - && match filepart.typ { + if self.parts.len() == 2 + && self.parts.first().map(|textpart| textpart.typ) == Some(Viewtype::Text) + && self + .parts + .get(1) + .map_or(false, |filepart| match filepart.typ { Viewtype::Image | Viewtype::Gif | Viewtype::Sticker @@ -680,24 +682,24 @@ impl MimeMessage { | Viewtype::File | Viewtype::Webxdc => true, Viewtype::Unknown | Viewtype::Text | Viewtype::VideochatInvitation => false, - }; - - if need_drop { - let mut filepart = self.parts.swap_remove(1); - - // insert new one - filepart.msg.clone_from(&self.parts[0].msg); - if let Some(quote) = self.parts[0].param.get(Param::Quote) { - filepart.param.set(Param::Quote, quote); - } - - // forget the one we use now - self.parts[0].msg = "".to_string(); + }) + { + let mut parts = std::mem::take(&mut self.parts); + let Some(mut filepart) = parts.pop() else { + // Should never happen. + return; + }; + let Some(textpart) = parts.pop() else { + // Should never happen. + return; + }; - // swap new with old - self.parts.push(filepart); // push to the end - let _ = self.parts.swap_remove(0); // drops first element, replacing it with the last one in O(1) + filepart.msg.clone_from(&textpart.msg); + if let Some(quote) = textpart.param.get(Param::Quote) { + filepart.param.set(Param::Quote, quote); } + + self.parts = vec![filepart]; } } From e7e5a4c2cc2193a58df17dc40697228faedee1e0 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 19:00:26 +0000 Subject: [PATCH 09/14] refactor: remove unused allow(clippy::indexing_slicing) for heuristically_parse_ndn --- src/mimeparser.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 4218ea6d74..5a435a14cc 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -1753,7 +1753,6 @@ impl MimeMessage { /// Some providers like GMX and Yahoo do not send standard NDNs (Non Delivery notifications). /// If you improve heuristics here you might also have to change prefetch_should_download() in imap/mod.rs. /// Also you should add a test in receive_imf.rs (there already are lots of test_parse_ndn_* tests). - #[allow(clippy::indexing_slicing)] async fn heuristically_parse_ndn(&mut self, context: &Context) { let maybe_ndn = if let Some(from) = self.get_header(HeaderDef::From_) { let from = from.to_ascii_lowercase(); From 60726c1dad99e8a36215a8d73f8ad90770d8bb52 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 19:11:18 +0000 Subject: [PATCH 10/14] refactor: remove indexing/slicing from `parse_message_ids` --- src/mimeparser.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 5a435a14cc..e2c7583aa4 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -1915,18 +1915,17 @@ pub(crate) struct DeliveryReport { pub failure: bool, } -#[allow(clippy::indexing_slicing)] pub(crate) fn parse_message_ids(ids: &str) -> Vec { // take care with mailparse::msgidparse() that is pretty untolerant eg. wrt missing `<` or `>` let mut msgids = Vec::new(); for id in ids.split_whitespace() { let mut id = id.to_string(); - if id.starts_with('<') { - id = id[1..].to_string(); - } - if id.ends_with('>') { - id = id[..id.len() - 1].to_string(); - } + if let Some(id_without_prefix) = id.strip_prefix('<') { + id = id_without_prefix.to_string(); + }; + if let Some(id_without_suffix) = id.strip_suffix('>') { + id = id_without_suffix.to_string(); + }; if !id.is_empty() { msgids.push(id); } From 762777ac0320d3e05494a72f32ff704c23414dac Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 20:00:48 +0000 Subject: [PATCH 11/14] refactor: remove slicing from `remove_bottom_quote` --- src/simplify.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/simplify.rs b/src/simplify.rs index b1b2171526..59fc8dfa7e 100644 --- a/src/simplify.rs +++ b/src/simplify.rs @@ -174,7 +174,6 @@ fn skip_forward_header<'a>(lines: &'a [&str]) -> (&'a [&'a str], bool) { } } -#[allow(clippy::indexing_slicing)] fn remove_bottom_quote<'a>(lines: &'a [&str]) -> (&'a [&'a str], Option) { let mut first_quoted_line = lines.len(); let mut last_quoted_line = None; @@ -189,24 +188,31 @@ fn remove_bottom_quote<'a>(lines: &'a [&str]) -> (&'a [&'a str], Option) } } if let Some(mut l_last) = last_quoted_line { - let quoted_text = lines[l_last..first_quoted_line] + let quoted_text = lines .iter() + .take(first_quoted_line) + .skip(l_last) .map(|s| { s.strip_prefix('>') .map_or(*s, |u| u.strip_prefix(' ').unwrap_or(u)) }) .collect::>() .join("\n"); - if l_last > 1 && is_empty_line(lines[l_last - 1]) { - l_last -= 1 + if l_last > 1 { + if let Some(line) = lines.get(l_last - 1) { + if is_empty_line(line) { + l_last -= 1 + } + } } if l_last > 1 { - let line = lines[l_last - 1]; - if is_quoted_headline(line) { - l_last -= 1 + if let Some(line) = lines.get(l_last - 1) { + if is_quoted_headline(line) { + l_last -= 1 + } } } - (&lines[..l_last], Some(quoted_text)) + (lines.get(..l_last).unwrap_or(lines), Some(quoted_text)) } else { (lines, None) } From c90a281087f893bbed0e882f3c0919f7cc699df9 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 20:03:39 +0000 Subject: [PATCH 12/14] refactor: get rid of slicing in `remove_top_quote` --- src/simplify.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/simplify.rs b/src/simplify.rs index 59fc8dfa7e..6e589a5fca 100644 --- a/src/simplify.rs +++ b/src/simplify.rs @@ -218,7 +218,6 @@ fn remove_bottom_quote<'a>(lines: &'a [&str]) -> (&'a [&'a str], Option) } } -#[allow(clippy::indexing_slicing)] fn remove_top_quote<'a>( lines: &'a [&str], is_chat_message: bool, @@ -245,10 +244,12 @@ fn remove_top_quote<'a>( } if let Some(last_quoted_line) = last_quoted_line { ( - &lines[last_quoted_line + 1..], + lines.get(last_quoted_line + 1..).unwrap_or(lines), Some( - lines[first_quoted_line..last_quoted_line + 1] + lines .iter() + .take(last_quoted_line + 1) + .skip(first_quoted_line) .map(|s| { s.strip_prefix('>') .map_or(*s, |u| u.strip_prefix(' ').unwrap_or(u)) From 51dccb10978f3390649f00dcdf8a4483449f9401 Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 20:10:20 +0000 Subject: [PATCH 13/14] refactor: remove unused allow(clippy::indexing_slicing) from 'truncate' --- src/tools.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools.rs b/src/tools.rs index f4a72fec0c..ef460316c7 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -45,7 +45,6 @@ use crate::stock_str; /// Shortens a string to a specified length and adds "[...]" to the /// end of the shortened string. -#[allow(clippy::indexing_slicing)] pub(crate) fn truncate(buf: &str, approx_chars: usize) -> Cow { let count = buf.chars().count(); if count > approx_chars + DC_ELLIPSIS.len() { From c5c5e14958292813d05efcba67c1a7237cca3e1d Mon Sep 17 00:00:00 2001 From: link2xt Date: Mon, 18 Nov 2024 20:11:16 +0000 Subject: [PATCH 14/14] refactor: forbid clippy::indexing_slicing It is impossible to allow this in the new code now. --- deltachat-contact-tools/src/lib.rs | 2 +- deltachat-jsonrpc/src/lib.rs | 1 + format-flowed/src/lib.rs | 1 + src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deltachat-contact-tools/src/lib.rs b/deltachat-contact-tools/src/lib.rs index e8ca3da3c3..4a6e5b037d 100644 --- a/deltachat-contact-tools/src/lib.rs +++ b/deltachat-contact-tools/src/lib.rs @@ -15,7 +15,7 @@ clippy::explicit_into_iter_loop, clippy::cloned_instead_of_copied )] -#![cfg_attr(not(test), warn(clippy::indexing_slicing))] +#![cfg_attr(not(test), forbid(clippy::indexing_slicing))] #![allow( clippy::match_bool, clippy::mixed_read_write_in_expression, diff --git a/deltachat-jsonrpc/src/lib.rs b/deltachat-jsonrpc/src/lib.rs index eb633cbd3f..912a6883a7 100644 --- a/deltachat-jsonrpc/src/lib.rs +++ b/deltachat-jsonrpc/src/lib.rs @@ -1,4 +1,5 @@ #![recursion_limit = "256"] +#![cfg_attr(not(test), forbid(clippy::indexing_slicing))] pub mod api; pub use yerpc; diff --git a/format-flowed/src/lib.rs b/format-flowed/src/lib.rs index 10f9400b55..055dd66778 100644 --- a/format-flowed/src/lib.rs +++ b/format-flowed/src/lib.rs @@ -8,6 +8,7 @@ //! is assumed to be set to "no". //! //! For received messages, DelSp parameter is honoured. +#![cfg_attr(not(test), forbid(clippy::indexing_slicing))] /// Wraps line to 72 characters using format=flowed soft breaks. /// diff --git a/src/lib.rs b/src/lib.rs index 2c35c8389b..7124bd5eb2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ clippy::explicit_into_iter_loop, clippy::cloned_instead_of_copied )] -#![cfg_attr(not(test), warn(clippy::indexing_slicing))] +#![cfg_attr(not(test), forbid(clippy::indexing_slicing))] #![allow( clippy::match_bool, clippy::mixed_read_write_in_expression,