fix(config): 优化 lua 数据校验逻辑
- 新增 parse_sequence 统一处理数组校验
This commit is contained in:
108
src/config.rs
108
src/config.rs
@@ -67,6 +67,7 @@ impl fmt::Display for ValueValidator {
|
||||
impl ValueValidator {
|
||||
/// 【纯粹校验入口】只进行逻辑与结构判定,零副作用、不产生内存分配
|
||||
pub fn validate(&self, value: &Value) -> mlua::Result<()> {
|
||||
let mut n = 0;
|
||||
if matches!(self, Self::Target) {
|
||||
println!("跟踪taget{}", value.type_name());
|
||||
}
|
||||
@@ -74,7 +75,8 @@ impl ValueValidator {
|
||||
println!("跟踪args2{}", value.type_name());
|
||||
}
|
||||
if matches!(self, Self::Env) {
|
||||
println!("跟踪env{}", value.type_name());
|
||||
n = n + 1;
|
||||
println!("跟踪env{} {}", n, value.type_name());
|
||||
}
|
||||
match self {
|
||||
Self::Target => match value {
|
||||
@@ -109,6 +111,38 @@ impl ValueValidator {
|
||||
},
|
||||
}
|
||||
}
|
||||
// fn parse_sequence(&self,index: i64,item: &Value) -> mlua::Result<()> {
|
||||
// match item {
|
||||
// Value::String(_) | Value::Integer(_) | Value::Number(_) | Value::Boolean(_) => {}
|
||||
// other => {
|
||||
// return Err(conversion_error(format!(
|
||||
// "第 {} 个元素类型无效: {}",
|
||||
// index,
|
||||
// other.type_name()
|
||||
// )));
|
||||
// }
|
||||
// }
|
||||
// Ok(())
|
||||
// }
|
||||
fn parse_sequence(&self, index: i64, item: &Value) -> mlua::Result<()> {
|
||||
match item {
|
||||
Value::String(_) | Value::Integer(_) | Value::Number(_) | Value::Boolean(_) => Ok(()),
|
||||
Value::Table(tbl) => match self {
|
||||
Self::Env => self.validate_sequence_table(tbl),
|
||||
Self::Args => Err(conversion_error(format!(
|
||||
"{} 仅支持一维数组,不能包含嵌套 Table,索引位置: {index}",
|
||||
self
|
||||
))),
|
||||
Self::Target => Err(conversion_error(format!("{} 仅支持字符串", self))),
|
||||
},
|
||||
other => Err(conversion_error(format!(
|
||||
"{} 第 {} 个元素类型无效: {}",
|
||||
self,
|
||||
index,
|
||||
other.type_name()
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
/// 校验 Table 是否为严格连续的纯数组,并递归校验其内部元素
|
||||
fn validate_sequence_table(&self, tbl: &Table) -> mlua::Result<()> {
|
||||
@@ -117,39 +151,10 @@ impl ValueValidator {
|
||||
// 1. 顺序遍历连续整数索引 1..N
|
||||
loop {
|
||||
let item: Value = tbl.raw_get(index)?;
|
||||
if matches!(item, Value::Nil) {
|
||||
if matches!(&item, Value::Nil) {
|
||||
break;
|
||||
}
|
||||
match self {
|
||||
Self::Args => match item {
|
||||
Value::Table(_) => {
|
||||
return Err(conversion_error(format!(
|
||||
"{} 仅支持一维数组,不能包含嵌套 Table,索引位置: {index}",
|
||||
self
|
||||
)));
|
||||
}
|
||||
Value::String(_)|Value::Integer(_)|Value::Number(_)|Value::Boolean(_) => {}
|
||||
_ => {return Err(conversion_error("args异常"))}
|
||||
},
|
||||
Self::Env => match item {
|
||||
Value::Table(_) => self.validate(&item)?,
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// // 元素规则判断
|
||||
// match item {
|
||||
// // Args 规则拦截:禁止嵌套数组
|
||||
// Value::Table(_) if matches!(self, Self::Args) => {
|
||||
// return Err(conversion_error(format!(
|
||||
// "{} 仅支持一维数组,不能包含嵌套 Table,索引位置{index}",
|
||||
// self
|
||||
// )));
|
||||
// }
|
||||
// // 标量或合法嵌套表:调用 validate 递归深度判定
|
||||
// _ => self.validate(&item)?,
|
||||
// }
|
||||
self.parse_sequence(index, &item)?;
|
||||
|
||||
index += 1;
|
||||
}
|
||||
@@ -206,6 +211,8 @@ impl ValueValidator {
|
||||
}
|
||||
Ok(raw_parts)
|
||||
}
|
||||
|
||||
/// 校验环境变量名的合法性(Windows 约束:非空、不含 '='、不含 NUL)
|
||||
fn parse_env_name(name: &Value) -> mlua::Result<String> {
|
||||
let name_str = match name {
|
||||
Value::String(s) => match s.to_str() {
|
||||
@@ -277,9 +284,12 @@ impl ValueValidator {
|
||||
};
|
||||
|
||||
let mut env_map = HashMap::new();
|
||||
|
||||
let mut n = 0i32;
|
||||
for pair in tbl.pairs::<Value, Value>() {
|
||||
n += 1;
|
||||
|
||||
let (raw_key, raw_val) = pair?;
|
||||
println!("env {} {}", n, raw_val.type_name());
|
||||
let (key, val) = Self::parse_env_pair(&raw_key, &raw_val)?;
|
||||
env_map.insert(key, val);
|
||||
}
|
||||
@@ -347,36 +357,6 @@ pub fn collect_value_into(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 校验环境变量名的合法性(Windows 约束:非空、不含 '='、不含 NUL)
|
||||
// fn parse_env_name(name: &Value, val: &Value) -> mlua::Result<String> {
|
||||
// let name_str = match name {
|
||||
// Value::String(s) => s.to_str()?.to_string(),
|
||||
//
|
||||
// _ => {
|
||||
// return Err(conversion_error(format!(
|
||||
// "env 配置解析失败:(对应的值: {}, 类型: {}) 无效的键值!示例 HOME=\"/home\" 或 PATH = {{ \"C:/tools/\", \"D:/Windows\"}})",
|
||||
// val.to_string()?,
|
||||
// val.type_name()
|
||||
// )));
|
||||
// }
|
||||
// };
|
||||
// if name_str.is_empty() {
|
||||
// return Err(conversion_error("环境变量名不能为空"));
|
||||
// }
|
||||
// if name_str.contains('=') {
|
||||
// return Err(conversion_error(format!(
|
||||
// "环境变量名 [{}] 不能包含 '='",
|
||||
// name_str
|
||||
// )));
|
||||
// }
|
||||
// if name_str.contains('\0') {
|
||||
// return Err(conversion_error(format!(
|
||||
// "环境变量名 [{}] 不能包含 NUL 字符",
|
||||
// name_str
|
||||
// )));
|
||||
// }
|
||||
// Ok(name_str)
|
||||
// }
|
||||
|
||||
/// 递归将任意 Lua Value 展开为扁平的字符串片段列表
|
||||
// fn collect_env_segments(value: Value, out: &mut Vec<OsString>) -> mlua::Result<()>{OK(())}
|
||||
@@ -503,7 +483,7 @@ mod tests {
|
||||
target = "C:/tools/git.exe",
|
||||
args = { "--no-pager"},
|
||||
env = {
|
||||
PATH = { "C:/tools/git/bin", "C:/Windows", get_env("PATH") },
|
||||
PATH = { "C:/tools/git/bin", "C:/Windows", get_env("PATH")},
|
||||
HOME = "C:/tools/home",
|
||||
CONST = 3,
|
||||
BOOL = true,
|
||||
|
||||
Reference in New Issue
Block a user