Fixed panic parsing broken HTMLs

This commit is contained in:
mdecimus 2025-01-15 10:10:02 +01:00
parent 6bb468ca5d
commit 4838e5faed
3 changed files with 41 additions and 11 deletions

View file

@ -23,7 +23,7 @@ members = [
[profile.dev] [profile.dev]
opt-level = 0 opt-level = 0
debug = 1 debug = 1
codegen-units = 4 #codegen-units = 4
lto = false lto = false
incremental = true incremental = true
panic = 'unwind' panic = 'unwind'

View file

@ -144,8 +144,16 @@ impl Queue {
Total = queue_events.len(), Total = queue_events.len(),
Details = self Details = self
.on_hold .on_hold
.keys() .values()
.copied() .fold([0, 0, 0], |mut acc, v| {
match v {
OnHold::InFlight => acc[0] += 1,
OnHold::ConcurrencyLimited { .. } => acc[1] += 1,
OnHold::Locked { .. } => acc[2] += 1,
}
acc
})
.into_iter()
.map(trc::Value::from) .map(trc::Value::from)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
Limit = max_in_flight, Limit = max_in_flight,
@ -176,7 +184,20 @@ impl Queue {
Queue(trc::QueueEvent::BackPressure), Queue(trc::QueueEvent::BackPressure),
Reason = "Queue outbound processing capacity for this node exceeded.", Reason = "Queue outbound processing capacity for this node exceeded.",
Total = queue_events.len(), Total = queue_events.len(),
Details = self.on_hold.keys().copied().map(trc::Value::from).collect::<Vec<_>>(), Details = self
.on_hold
.values()
.fold([0, 0, 0], |mut acc, v| {
match v {
OnHold::InFlight => acc[0] += 1,
OnHold::ConcurrencyLimited { .. } => acc[1] += 1,
OnHold::Locked { .. } => acc[2] += 1,
}
acc
})
.into_iter()
.map(trc::Value::from)
.collect::<Vec<_>>(),
Limit = max_in_flight, Limit = max_in_flight,
); );
} }

View file

@ -4,7 +4,7 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/ */
use mail_parser::decoders::html::add_html_token; use mail_parser::decoders::html::add_html_token;
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
pub enum HtmlToken { pub enum HtmlToken {
@ -201,10 +201,14 @@ pub fn html_to_tokens(input: &str) -> Vec<HtmlToken> {
match ch { match ch {
b'>' if !in_quote => { b'>' if !in_quote => {
if !value.is_empty() { if !value.is_empty() {
attributes.last_mut().unwrap().1 = let value =
String::from_utf8(value) String::from_utf8(value).unwrap_or_default();
.unwrap_or_default() if let Some((_, v)) = attributes.last_mut() {
.into(); *v = value.into();
} else {
// Broken attribute
attributes.push((0, Some(value)));
}
} }
break 'outer; break 'outer;
} }
@ -226,8 +230,13 @@ pub fn html_to_tokens(input: &str) -> Vec<HtmlToken> {
} }
if !value.is_empty() { if !value.is_empty() {
attributes.last_mut().unwrap().1 = let value = String::from_utf8(value).unwrap_or_default();
String::from_utf8(value).unwrap_or_default().into(); if let Some((_, v)) = attributes.last_mut() {
*v = value.into();
} else {
// Broken attribute
attributes.push((0, Some(value)));
}
} }
} }
b' ' | b'\t' | b'\r' | b'\n' => { b' ' | b'\t' | b'\r' | b'\n' => {