From dc08b91314a24df9f3005b226691b1185de0565d Mon Sep 17 00:00:00 2001 From: dai Date: Mon, 24 Mar 2025 19:34:51 +0100 Subject: [PATCH] Fix deadlock in stdio.format calls in tostring metamethod (#288) --- Cargo.lock | 1 + crates/lune-utils/Cargo.toml | 1 + crates/lune-utils/src/fmt/value/mod.rs | 12 +++++------- tests/stdio/format.luau | 20 ++++++++++++++++++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39f065e..8544491 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1742,6 +1742,7 @@ dependencies = [ "dunce", "mlua", "once_cell", + "parking_lot", "path-clean", "pathdiff", "semver 1.0.23", diff --git a/crates/lune-utils/Cargo.toml b/crates/lune-utils/Cargo.toml index 138f680..35cc291 100644 --- a/crates/lune-utils/Cargo.toml +++ b/crates/lune-utils/Cargo.toml @@ -22,4 +22,5 @@ dunce = "1.0" once_cell = "1.17" path-clean = "1.0" pathdiff = "0.2" +parking_lot = "0.12.3" semver = "1.0" diff --git a/crates/lune-utils/src/fmt/value/mod.rs b/crates/lune-utils/src/fmt/value/mod.rs index 3a3e310..bd29f55 100644 --- a/crates/lune-utils/src/fmt/value/mod.rs +++ b/crates/lune-utils/src/fmt/value/mod.rs @@ -1,11 +1,9 @@ -use std::{ - collections::HashSet, - sync::{Arc, Mutex}, -}; +use std::{collections::HashSet, sync::Arc}; use console::{colors_enabled as get_colors_enabled, set_colors_enabled}; use mlua::prelude::*; use once_cell::sync::Lazy; +use parking_lot::ReentrantMutex; mod basic; mod config; @@ -20,7 +18,7 @@ pub use self::config::ValueFormatConfig; // NOTE: Since the setting for colors being enabled is global, // and these functions may be called in parallel, we use this global // lock to make sure that we don't mess up the colors for other threads. -static COLORS_LOCK: Lazy>> = Lazy::new(|| Arc::new(Mutex::new(()))); +static COLORS_LOCK: Lazy>> = Lazy::new(|| Arc::new(ReentrantMutex::new(()))); /** Formats a Lua value into a pretty string using the given config. @@ -28,7 +26,7 @@ static COLORS_LOCK: Lazy>> = Lazy::new(|| Arc::new(Mutex::new(())) #[must_use] #[allow(clippy::missing_panics_doc)] pub fn pretty_format_value(value: &LuaValue, config: &ValueFormatConfig) -> String { - let _guard = COLORS_LOCK.lock().unwrap(); + let _guard = COLORS_LOCK.lock(); let were_colors_enabled = get_colors_enabled(); set_colors_enabled(were_colors_enabled && config.colors_enabled); @@ -48,7 +46,7 @@ pub fn pretty_format_value(value: &LuaValue, config: &ValueFormatConfig) -> Stri #[must_use] #[allow(clippy::missing_panics_doc)] pub fn pretty_format_multi_value(values: &LuaMultiValue, config: &ValueFormatConfig) -> String { - let _guard = COLORS_LOCK.lock().unwrap(); + let _guard = COLORS_LOCK.lock(); let were_colors_enabled = get_colors_enabled(); set_colors_enabled(were_colors_enabled && config.colors_enabled); diff --git a/tests/stdio/format.luau b/tests/stdio/format.luau index c0cc7cf..8d8f879 100644 --- a/tests/stdio/format.luau +++ b/tests/stdio/format.luau @@ -122,3 +122,23 @@ stdio.ewrite(typeof(errorMessage)) assertContains("Should format errors similarly to userdata", stdio.format(errorMessage), "