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]
opt-level = 0
debug = 1
codegen-units = 4
#codegen-units = 4
lto = false
incremental = true
panic = 'unwind'

View file

@ -144,8 +144,16 @@ impl Queue {
Total = queue_events.len(),
Details = self
.on_hold
.keys()
.copied()
.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,
@ -176,7 +184,20 @@ impl Queue {
Queue(trc::QueueEvent::BackPressure),
Reason = "Queue outbound processing capacity for this node exceeded.",
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,
);
}

View file

@ -4,7 +4,7 @@
* 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)]
pub enum HtmlToken {
@ -201,10 +201,14 @@ pub fn html_to_tokens(input: &str) -> Vec<HtmlToken> {
match ch {
b'>' if !in_quote => {
if !value.is_empty() {
attributes.last_mut().unwrap().1 =
String::from_utf8(value)
.unwrap_or_default()
.into();
let value =
String::from_utf8(value).unwrap_or_default();
if let Some((_, v)) = attributes.last_mut() {
*v = value.into();
} else {
// Broken attribute
attributes.push((0, Some(value)));
}
}
break 'outer;
}
@ -226,8 +230,13 @@ pub fn html_to_tokens(input: &str) -> Vec<HtmlToken> {
}
if !value.is_empty() {
attributes.last_mut().unwrap().1 =
String::from_utf8(value).unwrap_or_default().into();
let value = String::from_utf8(value).unwrap_or_default();
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' => {