Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: eliminating indexing_slicing #6214

Merged
merged 14 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deltachat-contact-tools/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions deltachat-jsonrpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![recursion_limit = "256"]
#![cfg_attr(not(test), forbid(clippy::indexing_slicing))]
pub mod api;
pub use yerpc;

Expand Down
1 change: 1 addition & 0 deletions format-flowed/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
1 change: 0 additions & 1 deletion src/authres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ fn parse_authservid_candidates_config(config: &Option<String>) -> BTreeSet<&str>

#[cfg(test)]
mod tests {
#![allow(clippy::indexing_slicing)]
use tokio::fs;
use tokio::io::AsyncReadExt;

Expand Down
2 changes: 0 additions & 2 deletions src/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 0 additions & 2 deletions src/configure/auto_mozilla.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,6 @@ pub(crate) async fn moz_autoconfigure(

#[cfg(test)]
mod tests {
#![allow(clippy::indexing_slicing)]

use super::*;

#[test]
Expand Down
2 changes: 0 additions & 2 deletions src/configure/auto_outlook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,6 @@ pub(crate) async fn outlk_autodiscover(

#[cfg(test)]
mod tests {
#![allow(clippy::indexing_slicing)]

use super::*;

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,8 +880,6 @@ async fn maybe_send_locations(context: &Context) -> Result<Option<u64>> {

#[cfg(test)]
mod tests {
#![allow(clippy::indexing_slicing)]

use super::*;
use crate::config::Config;
use crate::message::MessageState;
Expand Down
1 change: 0 additions & 1 deletion src/mimefactory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down
58 changes: 28 additions & 30 deletions src/mimeparser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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];
}
}

Expand Down Expand Up @@ -1751,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();
Expand Down Expand Up @@ -1914,18 +1915,17 @@ pub(crate) struct DeliveryReport {
pub failure: bool,
}

#[allow(clippy::indexing_slicing)]
pub(crate) fn parse_message_ids(ids: &str) -> Vec<String> {
// 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);
}
Expand Down Expand Up @@ -2362,8 +2362,6 @@ async fn ndn_maybe_add_info_msg(

#[cfg(test)]
mod tests {
#![allow(clippy::indexing_slicing)]

use mailparse::ParsedMail;

use super::*;
Expand Down
2 changes: 0 additions & 2 deletions src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
34 changes: 17 additions & 17 deletions src/qr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,10 @@ pub fn format_backup(qr: &Qr) -> Result<String> {
/// 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<Qr> {
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
Expand Down Expand Up @@ -546,7 +547,7 @@ async fn decode_ideltachat(context: &Context, prefix: &str, qr: &str) -> Result<
fn decode_account(qr: &str) -> Result<Qr> {
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 {
Expand All @@ -564,7 +565,7 @@ fn decode_account(qr: &str) -> Result<Qr> {
fn decode_webrtc_instance(_context: &Context, qr: &str) -> Result<Qr> {
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")?;
Expand Down Expand Up @@ -637,7 +638,7 @@ fn decode_shadowsocks_proxy(qr: &str) -> Result<Qr> {
fn decode_backup2(qr: &str) -> Result<Qr> {
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")?;
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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<Qr> {
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..])
Expand Down Expand Up @@ -855,9 +858,8 @@ async fn decode_mailto(context: &Context, qr: &str) -> Result<Qr> {
/// Extract address for the smtp scheme.
///
/// Scheme: `SMTP:addr...:subject...:body...`
#[allow(clippy::indexing_slicing)]
async fn decode_smtp(context: &Context, qr: &str) -> Result<Qr> {
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]
Expand All @@ -875,14 +877,13 @@ async fn decode_smtp(context: &Context, qr: &str) -> Result<Qr> {
/// 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<Qr> {
// 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
}
Expand All @@ -903,7 +904,6 @@ static VCARD_EMAIL_RE: Lazy<regex::Regex> =
/// Extract address for the vcard scheme.
///
/// Scheme: `VCARD:BEGIN\nN:last name;first name;...;\nEMAIL;<type>:addr...;`
#[allow(clippy::indexing_slicing)]
async fn decode_vcard(context: &Context, qr: &str) -> Result<Qr> {
let name = VCARD_NAME_RE
.captures(qr)
Expand All @@ -915,8 +915,8 @@ async fn decode_vcard(context: &Context, qr: &str) -> Result<Qr> {
})
.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");
};
Expand Down
15 changes: 10 additions & 5 deletions src/receive_imf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
};

Expand Down Expand Up @@ -2519,8 +2521,11 @@ fn compute_mailinglist_name(
// 51231231231231231231231232869f58.xing.com -> xing.com
static PREFIX_32_CHARS_HEX: Lazy<Regex> =
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();
}
Expand Down
1 change: 0 additions & 1 deletion src/securejoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading
Loading