From ee7120a94be6e6c8aef614326a669981a2e58237 Mon Sep 17 00:00:00 2001 From: Risu <79110363+risu729@users.noreply.github.com> Date: Fri, 12 Sep 2025 00:55:53 +1000 Subject: [PATCH 1/2] fix(env): disallow nested env objects --- src/config/config_file/mise_toml.rs | 173 ++++------------------------ src/config/env_directive/mod.rs | 4 +- 2 files changed, 28 insertions(+), 149 deletions(-) diff --git a/src/config/config_file/mise_toml.rs b/src/config/config_file/mise_toml.rs index 3b3d2fc9b8..9af4618bce 100644 --- a/src/config/config_file/mise_toml.rs +++ b/src/config/config_file/mise_toml.rs @@ -930,161 +930,38 @@ impl<'de> de::Deserialize<'de> for EnvList { } } _ => { - enum Val { - Int(i64), + #[derive(Deserialize)] + #[serde(untagged)] + pub enum PrimitiveVal { Str(String), + Int(i64), Bool(bool), + } + #[derive(Deserialize)] + #[serde(untagged)] + enum Val { + Primitive(PrimitiveVal), Map { - value: Box, - tools: bool, - redact: bool, + value: PrimitiveVal, + #[serde(flatten)] + options: EnvDirectiveOptions, }, } - impl Display for Val { - fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - match self { - Val::Int(i) => write!(f, "{i}"), - Val::Str(s) => write!(f, "{s}"), - Val::Bool(b) => write!(f, "{b}"), - Val::Map { - value, - tools, - redact, - } => { - write!(f, "{value}")?; - if *tools { - write!(f, " tools")?; - } - if *redact { - write!(f, " redact")?; - } - Ok(()) - } - } - } - } - - impl<'de> de::Deserialize<'de> for Val { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct ValVisitor; - - impl<'de> Visitor<'de> for ValVisitor { - type Value = Val; - fn expecting( - &self, - formatter: &mut Formatter, - ) -> std::fmt::Result - { - formatter.write_str("env value") - } - - fn visit_bool(self, v: bool) -> Result - where - E: de::Error, - { - Ok(Val::Bool(v)) - } - - fn visit_i64(self, v: i64) -> Result - where - E: de::Error, - { - Ok(Val::Int(v)) - } - - fn visit_str(self, v: &str) -> Result - where - E: de::Error, - { - Ok(Val::Str(v.to_string())) - } - - fn visit_map( - self, - mut map: A, - ) -> Result - where - A: de::MapAccess<'de>, - { - let mut value: Option = None; - let mut tools = None; - let mut redact = None; - while let Some((key, val)) = - map.next_entry::()? - { - match key.as_str() { - "value" => { - value = Some(val); - } - "tools" => { - tools = Some(val); - } - "redact" => { - redact = Some(val); - } - _ => { - return Err(de::Error::unknown_field( - &key, - &["value", "tools", "redact"], - )); - } - } - } - let value = value - .ok_or_else(|| de::Error::missing_field("value"))?; - let tools = if let Some(Val::Bool(tools)) = tools { - tools - } else { - false - }; - Ok(Val::Map { - value: Box::new(value), - tools, - redact: redact - .map(|r| { - if let Val::Bool(b) = r { b } else { false } - }) - .unwrap_or_default(), - }) - } - } - - deserializer.deserialize_any(ValVisitor) - } - } - - let value = map.next_value::()?; - match value { - Val::Int(i) => { - env.push(EnvDirective::Val( - key, - i.to_string(), - Default::default(), - )); - } - Val::Str(s) => { - env.push(EnvDirective::Val(key, s, Default::default())); + let (value, options) = match map.next_value::()? { + Val::Primitive(p) => (p, EnvDirectiveOptions::default()), + Val::Map { value, options } => (value, options), + }; + let directive = match value { + PrimitiveVal::Str(s) => EnvDirective::Val(key, s, options), + PrimitiveVal::Int(i) => { + EnvDirective::Val(key, i.to_string(), options) } - Val::Bool(true) => env.push(EnvDirective::Val( - key, - "true".into(), - Default::default(), - )), - Val::Bool(false) => { - env.push(EnvDirective::Rm(key, Default::default())) + PrimitiveVal::Bool(true) => { + EnvDirective::Val(key, "true".to_string(), options) } - Val::Map { - value, - tools, - redact, - } => { - let opts = EnvDirectiveOptions { tools, redact }; - env.push(EnvDirective::Val(key, value.to_string(), opts)); - } - } + PrimitiveVal::Bool(false) => EnvDirective::Rm(key, options), + }; + env.push(directive); } } } diff --git a/src/config/env_directive/mod.rs b/src/config/env_directive/mod.rs index 7646b0a613..74c9cd92fd 100644 --- a/src/config/env_directive/mod.rs +++ b/src/config/env_directive/mod.rs @@ -21,9 +21,11 @@ mod path; mod source; mod venv; -#[derive(Debug, Clone, Default, PartialEq, serde::Serialize)] +#[derive(Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize)] pub struct EnvDirectiveOptions { + #[serde(default)] pub(crate) tools: bool, + #[serde(default)] pub(crate) redact: bool, } From 8f79feb99dc61c27e95aa45ce435b1e45764b7cb Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 11 Sep 2025 15:02:34 +0000 Subject: [PATCH 2/2] [autofix.ci] apply automated fixes --- src/config/config_file/mise_toml.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/config_file/mise_toml.rs b/src/config/config_file/mise_toml.rs index 9af4618bce..7466dbbe7a 100644 --- a/src/config/config_file/mise_toml.rs +++ b/src/config/config_file/mise_toml.rs @@ -5,7 +5,7 @@ use once_cell::sync::OnceCell; use serde::de::Visitor; use serde::{Deserializer, de}; use serde_derive::Deserialize; -use std::fmt::{Debug, Display, Formatter}; +use std::fmt::{Debug, Formatter}; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::{