From b98ad21287cf086278ec617db68a2c3ba9a97c40 Mon Sep 17 00:00:00 2001 From: NePank Date: Thu, 11 Dec 2025 16:04:41 +0100 Subject: [PATCH 1/3] FIXED undefined behavior in style_to_font function. --- Cargo.toml | 1 - src/backend/mod.rs | 22 ++++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d99fc37..857f9ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,6 @@ plotters = { version = "0.3", default-features = false } plotters-backend = "0.3" iced_widget = { version = "0.14", features = ["canvas"] } iced_graphics = "0.14" -once_cell = "1" [dev-dependencies] plotters = { version = "0.3", default-features = false, features = [ diff --git a/src/backend/mod.rs b/src/backend/mod.rs index cc5ad2a..e11ba33 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -14,7 +14,6 @@ use iced_widget::{ text::Alignment, text::Shaping, }; -use once_cell::unsync::Lazy; use plotters_backend::{ //FontTransform, BackendColor, @@ -27,7 +26,7 @@ use plotters_backend::{ FontStyle, text_anchor, }; -use std::collections::HashSet; +use std::sync::{LazyLock, Mutex}; /// The Iced drawing backend pub(crate) struct IcedChartBackend<'a, B> { @@ -302,10 +301,9 @@ where } } -#[allow(static_mut_refs)] fn style_to_font(style: &S) -> Font { // iced font family requires static str - static mut FONTS: Lazy> = Lazy::new(HashSet::new); + static FONTS: LazyLock>> = LazyLock::new(|| Mutex::new(Vec::new())); Font { family: match style.family() { @@ -313,13 +311,17 @@ fn style_to_font(style: &S) -> Font { FontFamily::SansSerif => font::Family::SansSerif, FontFamily::Monospace => font::Family::Monospace, FontFamily::Name(s) => { - let s = unsafe { - if !FONTS.contains(s) { - FONTS.insert(String::from(s)); + if let Ok(mut vec_guard) = FONTS.lock() { + if let Some(&s) = vec_guard.iter().find(|&&vec_str| vec_str == s) { + font::Family::Name(s) + } else { + let leaked_str = &Box::leak(Box::new(String::from(s)))[..]; + vec_guard.push(&leaked_str); + font::Family::Name(leaked_str) } - FONTS.get(s).unwrap().as_str() - }; - font::Family::Name(s) + } else { + font::Family::default() + } } }, weight: match style.style() { From 99aae0e6df7d4145e2ba89228ad2d3efb114d202 Mon Sep 17 00:00:00 2001 From: serpack Date: Thu, 11 Dec 2025 18:28:16 +0100 Subject: [PATCH 2/3] - changed vec to hashset - changed "if let some" to map_or_else --- src/backend/mod.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/backend/mod.rs b/src/backend/mod.rs index e11ba33..0e64fb9 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -26,6 +26,7 @@ use plotters_backend::{ FontStyle, text_anchor, }; +use std::collections::HashSet; use std::sync::{LazyLock, Mutex}; /// The Iced drawing backend @@ -303,26 +304,25 @@ where fn style_to_font(style: &S) -> Font { // iced font family requires static str - static FONTS: LazyLock>> = LazyLock::new(|| Mutex::new(Vec::new())); + static FONTS: LazyLock>> = + LazyLock::new(|| Mutex::new(HashSet::new())); Font { family: match style.family() { FontFamily::Serif => font::Family::Serif, FontFamily::SansSerif => font::Family::SansSerif, FontFamily::Monospace => font::Family::Monospace, - FontFamily::Name(s) => { - if let Ok(mut vec_guard) = FONTS.lock() { - if let Some(&s) = vec_guard.iter().find(|&&vec_str| vec_str == s) { - font::Family::Name(s) - } else { + FontFamily::Name(s) => FONTS.lock().map_or_else( + |_| font::Family::default(), + |mut vec_guard| { + if !vec_guard.contains(s) { let leaked_str = &Box::leak(Box::new(String::from(s)))[..]; - vec_guard.push(&leaked_str); - font::Family::Name(leaked_str) + vec_guard.insert(&leaked_str); } - } else { - font::Family::default() - } - } + + font::Family::Name(vec_guard.get(s).unwrap()) + }, + ), }, weight: match style.style() { FontStyle::Bold => font::Weight::Bold, From 94b6ccd873978e96f99095c4e98b4b9d395718c3 Mon Sep 17 00:00:00 2001 From: serpack Date: Wed, 24 Dec 2025 21:36:56 +0100 Subject: [PATCH 3/3] leak string without box::leak --- src/backend/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 0e64fb9..5ee57a2 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -316,11 +316,10 @@ fn style_to_font(style: &S) -> Font { |_| font::Family::default(), |mut vec_guard| { if !vec_guard.contains(s) { - let leaked_str = &Box::leak(Box::new(String::from(s)))[..]; - vec_guard.insert(&leaked_str); + vec_guard.insert(String::from(s).leak()); } - font::Family::Name(vec_guard.get(s).unwrap()) + font::Family::Name(*vec_guard.get(s).unwrap()) }, ), },