1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 05:12:40 +03:00

Add cycle detection when converting lua values to dynamic

This commit is contained in:
Wez Furlong 2022-05-17 21:53:36 -07:00
parent 862dbc604a
commit 55e7d845e9
8 changed files with 25 additions and 12 deletions

6
Cargo.lock generated
View File

@ -2021,7 +2021,6 @@ dependencies = [
"bstr 0.2.17", "bstr 0.2.17",
"log", "log",
"mlua", "mlua",
"strsim 0.10.0",
"wezterm-dynamic", "wezterm-dynamic",
] ]
@ -2229,9 +2228,8 @@ dependencies = [
[[package]] [[package]]
name = "mlua" name = "mlua"
version = "0.7.4" version = "0.8.0-beta.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/wez/mlua?branch=table_to_pointer#7884481691169044c18a77ec495886db0d02bee9"
checksum = "29e2194305aa8301d5da9c1c98640047f4219f6b95c190f6860338ab9872b686"
dependencies = [ dependencies = [
"bstr 0.2.17", "bstr 0.2.17",
"cc", "cc",

View File

@ -24,3 +24,4 @@ split-debuginfo = "unpacked"
[patch.crates-io] [patch.crates-io]
xcb = {version="1.1", git="https://github.com/wez/rust-xcb", branch="ffi"} xcb = {version="1.1", git="https://github.com/wez/rust-xcb", branch="ffi"}
mlua = {version="0.8.0-beta.4", git="https://github.com/wez/mlua", branch="table_to_pointer"}

View File

@ -25,7 +25,7 @@ lazy_static = "1.4"
libc = "0.2" libc = "0.2"
log = "0.4" log = "0.4"
luahelper = { path = "../luahelper" } luahelper = { path = "../luahelper" }
mlua = {version="0.7", features=["vendored", "lua54", "async", "send"]} mlua = {version="0.8.0-beta.4", features=["vendored", "lua54", "async", "send"]}
# file change notification # file change notification
notify = "4.0" notify = "4.0"
open = "2.0" open = "2.0"

View File

@ -705,7 +705,7 @@ impl Config {
// file. Note that we can't catch this happening for files that are // file. Note that we can't catch this happening for files that are
// imported via the lua require function. // imported via the lua require function.
lua.load(s.trim_start_matches('\u{FEFF}')) lua.load(s.trim_start_matches('\u{FEFF}'))
.set_name(p.to_string_lossy().as_bytes())? .set_name(p.to_string_lossy())?
.eval_async(), .eval_async(),
)?; )?;
let config = Self::apply_overrides_to(&lua, config)?; let config = Self::apply_overrides_to(&lua, config)?;

View File

@ -9,6 +9,5 @@ edition = "2018"
[dependencies] [dependencies]
bstr = "0.2" bstr = "0.2"
log = "0.4" log = "0.4"
mlua = "0.7" mlua = "0.8.0-beta.4"
strsim = "0.10"
wezterm-dynamic = { path = "../wezterm-dynamic" } wezterm-dynamic = { path = "../wezterm-dynamic" }

View File

@ -2,7 +2,7 @@
pub use mlua; pub use mlua;
use mlua::{ToLua, Value as LuaValue}; use mlua::{ToLua, Value as LuaValue};
use std::collections::BTreeMap; use std::collections::{BTreeMap, HashSet};
use wezterm_dynamic::{FromDynamic, ToDynamic, Value as DynValue}; use wezterm_dynamic::{FromDynamic, ToDynamic, Value as DynValue};
/// Implement lua conversion traits for a type. /// Implement lua conversion traits for a type.
@ -76,8 +76,15 @@ pub fn dynamic_to_lua_value<'lua>(
}) })
} }
/// FIXME: lua_value_to_dynamic should detect and avoid cycles in the underlying lua object
pub fn lua_value_to_dynamic(value: LuaValue) -> mlua::Result<DynValue> { pub fn lua_value_to_dynamic(value: LuaValue) -> mlua::Result<DynValue> {
let mut visited = HashSet::new();
lua_value_to_dynamic_impl(value, &mut visited)
}
fn lua_value_to_dynamic_impl(
value: LuaValue,
visited: &mut HashSet<usize>,
) -> mlua::Result<DynValue> {
Ok(match value { Ok(match value {
LuaValue::Nil => DynValue::Null, LuaValue::Nil => DynValue::Null,
LuaValue::String(s) => DynValue::String(s.to_str()?.to_string()), LuaValue::String(s) => DynValue::String(s.to_str()?.to_string()),
@ -107,6 +114,14 @@ pub fn lua_value_to_dynamic(value: LuaValue) -> mlua::Result<DynValue> {
} }
LuaValue::Error(e) => return Err(e), LuaValue::Error(e) => return Err(e),
LuaValue::Table(table) => { LuaValue::Table(table) => {
let ptr = table.to_pointer() as usize;
if visited.contains(&ptr) {
// Skip this one, as we've seen it before.
// Treat it as a Null value.
return Ok(DynValue::Null);
}
visited.insert(ptr);
if let Ok(true) = table.contains_key(1) { if let Ok(true) = table.contains_key(1) {
let mut array = vec![]; let mut array = vec![];
for value in table.sequence_values() { for value in table.sequence_values() {

View File

@ -22,7 +22,7 @@ libc = "0.2"
log = "0.4" log = "0.4"
luahelper = { path = "../luahelper" } luahelper = { path = "../luahelper" }
metrics = { version="0.17", features=["std"]} metrics = { version="0.17", features=["std"]}
mlua = "0.7" mlua = "0.8.0-beta.4"
names = { version = "0.12", default-features = false } names = { version = "0.12", default-features = false }
percent-encoding = "2" percent-encoding = "2"
portable-pty = { path = "../pty", features = ["serde_support"]} portable-pty = { path = "../pty", features = ["serde_support"]}

View File

@ -42,7 +42,7 @@ log = "0.4"
lru = "0.7" lru = "0.7"
luahelper = { path = "../luahelper" } luahelper = { path = "../luahelper" }
metrics = { version="0.17", features=["std"]} metrics = { version="0.17", features=["std"]}
mlua = "0.7" mlua = "0.8.0-beta.4"
mux = { path = "../mux" } mux = { path = "../mux" }
open = "2.0" open = "2.0"
ordered-float = "3.0" ordered-float = "3.0"