Bump to Rust 2024
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "spam-filter"
|
||||
version = "0.11.5"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
resolver = "2"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
use std::{collections::HashSet, future::Future, vec};
|
||||
|
||||
use common::{
|
||||
scripts::{
|
||||
functions::{array::cosine_similarity, unicode::CharUtils},
|
||||
IsMixedCharset,
|
||||
},
|
||||
Server,
|
||||
scripts::{
|
||||
IsMixedCharset,
|
||||
functions::{array::cosine_similarity, unicode::CharUtils},
|
||||
},
|
||||
};
|
||||
use mail_parser::{HeaderName, MimeHeaders, PartType};
|
||||
use nlp::tokenizers::types::TokenType;
|
||||
@@ -291,7 +291,7 @@ impl SpamFilterAnalyzeMime for Server {
|
||||
&& ct_subtype == "plain"
|
||||
&& ct
|
||||
.and_then(|ct| ct.attribute("charset"))
|
||||
.map_or(true, |c| c.is_empty())
|
||||
.is_none_or(|c| c.is_empty())
|
||||
{
|
||||
// Charset header is missing
|
||||
ctx.result.add_tag("MISSING_CHARSET");
|
||||
@@ -339,7 +339,7 @@ impl SpamFilterAnalyzeMime for Server {
|
||||
"octet-stream" => {
|
||||
if !is_encrypted
|
||||
&& !has_content_id
|
||||
&& cd.map_or(true, |cd| {
|
||||
&& cd.is_none_or(|cd| {
|
||||
!cd.c_type.eq_ignore_ascii_case("attachment")
|
||||
&& !cd.has_attribute("filename")
|
||||
})
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
use common::{scripts::functions::text::levenshtein_distance, Server};
|
||||
use common::{Server, scripts::functions::text::levenshtein_distance};
|
||||
use mail_parser::HeaderName;
|
||||
use smtp_proto::{MAIL_BODY_8BITMIME, MAIL_BODY_BINARYMIME, MAIL_SMTPUTF8};
|
||||
use store::ahash::HashSet;
|
||||
@@ -85,7 +85,7 @@ impl SpamFilterAnalyzeRecipient for Server {
|
||||
// Validate unnecessary encoding in recipient headers
|
||||
let raw_utf8 = raw_utf8.unwrap_or_default();
|
||||
if recipients.iter().all(|rcpt| {
|
||||
rcpt.name.as_ref().map_or(true, |name| name.is_ascii())
|
||||
rcpt.name.as_ref().is_none_or(|name| name.is_ascii())
|
||||
&& rcpt.email.address.is_ascii()
|
||||
}) && raw_utf8.contains("=?")
|
||||
&& raw_utf8.contains("?=")
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
use std::{borrow::Cow, collections::HashSet, future::Future, time::Duration};
|
||||
|
||||
use common::{ip_to_bytes, Server, KV_BAYES_MODEL_GLOBAL, KV_BAYES_MODEL_USER};
|
||||
use common::{KV_BAYES_MODEL_GLOBAL, KV_BAYES_MODEL_USER, Server, ip_to_bytes};
|
||||
use mail_auth::DmarcResult;
|
||||
use nlp::{
|
||||
bayes::{
|
||||
tokenize::{symbols, BayesInputToken, BayesTokenizer},
|
||||
BayesModel, TokenHash, Weights,
|
||||
tokenize::{BayesInputToken, BayesTokenizer, symbols},
|
||||
},
|
||||
tokenizers::{
|
||||
osb::{Gram, OsbToken, OsbTokenizer},
|
||||
@@ -22,7 +22,7 @@ use store::dispatch::lookup::KeyValue;
|
||||
use trc::AddContext;
|
||||
use utils::cache::TtlEntry;
|
||||
|
||||
use crate::{analysis::url::UrlParts, Email, IpParts, SpamFilterContext, TextPart};
|
||||
use crate::{Email, IpParts, SpamFilterContext, TextPart, analysis::url::UrlParts};
|
||||
|
||||
pub trait BayesClassifier {
|
||||
fn bayes_train(
|
||||
@@ -116,9 +116,11 @@ impl BayesClassifier for Server {
|
||||
}
|
||||
|
||||
if model.weights.is_empty() {
|
||||
trc::bail!(trc::SpamEvent::TrainError
|
||||
.into_err()
|
||||
.reason("No weights found"));
|
||||
trc::bail!(
|
||||
trc::SpamEvent::TrainError
|
||||
.into_err()
|
||||
.reason("No weights found")
|
||||
);
|
||||
}
|
||||
|
||||
trc::event!(
|
||||
@@ -216,8 +218,7 @@ impl BayesClassifier for Server {
|
||||
ctx.input.account_id,
|
||||
TokenHash::from(Gram::Uni { t1: &token }),
|
||||
)
|
||||
.await
|
||||
.map(Weights::from)?;
|
||||
.await?;
|
||||
osb_tokens.push(OsbToken {
|
||||
inner: weights,
|
||||
idx: 1,
|
||||
@@ -234,8 +235,7 @@ impl BayesClassifier for Server {
|
||||
) {
|
||||
let weights = self
|
||||
.bayes_weights_for_token(ctx.input.account_id, token.inner)
|
||||
.await
|
||||
.map(Weights::from)?;
|
||||
.await?;
|
||||
osb_tokens.push(OsbToken {
|
||||
inner: weights,
|
||||
idx: token.idx,
|
||||
@@ -260,8 +260,7 @@ impl BayesClassifier for Server {
|
||||
) {
|
||||
let weights = self
|
||||
.bayes_weights_for_token(ctx.input.account_id, token.inner)
|
||||
.await
|
||||
.map(Weights::from)?;
|
||||
.await?;
|
||||
osb_tokens.push(OsbToken {
|
||||
inner: weights,
|
||||
idx: token.idx,
|
||||
@@ -275,8 +274,7 @@ impl BayesClassifier for Server {
|
||||
) {
|
||||
let weights = self
|
||||
.bayes_weights_for_token(ctx.input.account_id, token.inner)
|
||||
.await
|
||||
.map(Weights::from)?;
|
||||
.await?;
|
||||
osb_tokens.push(OsbToken {
|
||||
inner: weights,
|
||||
idx: token.idx,
|
||||
@@ -365,10 +363,11 @@ impl BayesClassifier for Server {
|
||||
};
|
||||
|
||||
if let Some(account_id) = ctx.input.account_id {
|
||||
trc::error!(err
|
||||
.span_id(ctx.input.span_id)
|
||||
.account_id(account_id)
|
||||
.caused_by(trc::location!()));
|
||||
trc::error!(
|
||||
err.span_id(ctx.input.span_id)
|
||||
.account_id(account_id)
|
||||
.caused_by(trc::location!())
|
||||
);
|
||||
} else {
|
||||
trc::error!(err.span_id(ctx.input.span_id).caused_by(trc::location!()));
|
||||
}
|
||||
|
||||
@@ -25,46 +25,46 @@ pub enum HtmlToken {
|
||||
}
|
||||
|
||||
pub(crate) const A: u64 = b'a' as u64;
|
||||
pub(crate) const IMG: u64 = (b'i' as u64) | (b'm' as u64) << 8 | (b'g' as u64) << 16;
|
||||
pub(crate) const IMG: u64 = (b'i' as u64) | ((b'm' as u64) << 8) | ((b'g' as u64) << 16);
|
||||
pub(crate) const HEAD: u64 =
|
||||
(b'h' as u64) | (b'e' as u64) << 8 | (b'a' as u64) << 16 | (b'd' as u64) << 24;
|
||||
(b'h' as u64) | ((b'e' as u64) << 8) | ((b'a' as u64) << 16) | ((b'd' as u64) << 24);
|
||||
pub(crate) const BODY: u64 =
|
||||
(b'b' as u64) | (b'o' as u64) << 8 | (b'd' as u64) << 16 | (b'y' as u64) << 24;
|
||||
(b'b' as u64) | ((b'o' as u64) << 8) | ((b'd' as u64) << 16) | ((b'y' as u64) << 24);
|
||||
pub(crate) const META: u64 =
|
||||
(b'm' as u64) | (b'e' as u64) << 8 | (b't' as u64) << 16 | (b'a' as u64) << 24;
|
||||
(b'm' as u64) | ((b'e' as u64) << 8) | ((b't' as u64) << 16) | ((b'a' as u64) << 24);
|
||||
pub(crate) const LINK: u64 =
|
||||
(b'l' as u64) | (b'i' as u64) << 8 | (b'n' as u64) << 16 | (b'k' as u64) << 24;
|
||||
(b'l' as u64) | ((b'i' as u64) << 8) | ((b'n' as u64) << 16) | ((b'k' as u64) << 24);
|
||||
|
||||
pub(crate) const HREF: u64 =
|
||||
(b'h' as u64) | (b'r' as u64) << 8 | (b'e' as u64) << 16 | (b'f' as u64) << 24;
|
||||
pub(crate) const SRC: u64 = (b's' as u64) | (b'r' as u64) << 8 | (b'c' as u64) << 16;
|
||||
(b'h' as u64) | ((b'r' as u64) << 8) | ((b'e' as u64) << 16) | ((b'f' as u64) << 24);
|
||||
pub(crate) const SRC: u64 = (b's' as u64) | ((b'r' as u64) << 8) | ((b'c' as u64) << 16);
|
||||
pub(crate) const WIDTH: u64 = (b'w' as u64)
|
||||
| (b'i' as u64) << 8
|
||||
| (b'd' as u64) << 16
|
||||
| (b't' as u64) << 24
|
||||
| (b'h' as u64) << 32;
|
||||
| ((b'i' as u64) << 8)
|
||||
| ((b'd' as u64) << 16)
|
||||
| ((b't' as u64) << 24)
|
||||
| ((b'h' as u64) << 32);
|
||||
pub(crate) const HEIGHT: u64 = (b'h' as u64)
|
||||
| (b'e' as u64) << 8
|
||||
| (b'i' as u64) << 16
|
||||
| (b'g' as u64) << 24
|
||||
| (b'h' as u64) << 32
|
||||
| (b't' as u64) << 40;
|
||||
pub(crate) const REL: u64 = (b'r' as u64) | (b'e' as u64) << 8 | (b'l' as u64) << 16;
|
||||
| ((b'e' as u64) << 8)
|
||||
| ((b'i' as u64) << 16)
|
||||
| ((b'g' as u64) << 24)
|
||||
| ((b'h' as u64) << 32)
|
||||
| ((b't' as u64) << 40);
|
||||
pub(crate) const REL: u64 = (b'r' as u64) | ((b'e' as u64) << 8) | ((b'l' as u64) << 16);
|
||||
pub(crate) const CONTENT: u64 = (b'c' as u64)
|
||||
| (b'o' as u64) << 8
|
||||
| (b'n' as u64) << 16
|
||||
| (b't' as u64) << 24
|
||||
| (b'e' as u64) << 32
|
||||
| (b'n' as u64) << 40
|
||||
| (b't' as u64) << 48;
|
||||
| ((b'o' as u64) << 8)
|
||||
| ((b'n' as u64) << 16)
|
||||
| ((b't' as u64) << 24)
|
||||
| ((b'e' as u64) << 32)
|
||||
| ((b'n' as u64) << 40)
|
||||
| ((b't' as u64) << 48);
|
||||
pub(crate) const HTTP_EQUIV: u64 = (b'h' as u64)
|
||||
| (b't' as u64) << 8
|
||||
| (b't' as u64) << 16
|
||||
| (b'p' as u64) << 24
|
||||
| (b'-' as u64) << 32
|
||||
| (b'e' as u64) << 40
|
||||
| (b'q' as u64) << 48
|
||||
| (b'u' as u64) << 56;
|
||||
| ((b't' as u64) << 8)
|
||||
| ((b't' as u64) << 16)
|
||||
| ((b'p' as u64) << 24)
|
||||
| ((b'-' as u64) << 32)
|
||||
| ((b'e' as u64) << 40)
|
||||
| ((b'q' as u64) << 48)
|
||||
| ((b'u' as u64) << 56);
|
||||
|
||||
pub fn html_to_tokens(input: &str) -> Vec<HtmlToken> {
|
||||
let input = input.as_bytes();
|
||||
@@ -98,7 +98,7 @@ pub fn html_to_tokens(input: &str) -> Vec<HtmlToken> {
|
||||
});
|
||||
}
|
||||
|
||||
while matches!(iter.peek(), Some((_, &ch)) if ch.is_ascii_whitespace()) {
|
||||
while matches!(iter.peek(), Some(&(_, &ch)) if ch.is_ascii_whitespace()) {
|
||||
pos += 1;
|
||||
iter.next();
|
||||
}
|
||||
@@ -135,7 +135,7 @@ pub fn html_to_tokens(input: &str) -> Vec<HtmlToken> {
|
||||
let mut is_end_tag = false;
|
||||
loop {
|
||||
match iter.peek() {
|
||||
Some((_, &b'/')) => {
|
||||
Some(&(_, &b'/')) => {
|
||||
is_end_tag = true;
|
||||
pos += 1;
|
||||
iter.next();
|
||||
@@ -184,7 +184,7 @@ pub fn html_to_tokens(input: &str) -> Vec<HtmlToken> {
|
||||
in_quote = !in_quote;
|
||||
}
|
||||
b'=' if !in_quote => {
|
||||
while matches!(iter.peek(), Some((_, &ch)) if ch.is_ascii_whitespace())
|
||||
while matches!(iter.peek(), Some(&(_, &ch)) if ch.is_ascii_whitespace())
|
||||
{
|
||||
iter.next();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user