fix(config): 优化配置解析
- 完善 `FromLua` 转换与边界校验,拦截空洞 (`nil`) 及非整数键
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::error::ShimError;
|
||||
use crate::{ShimConfig, ShimLayout};
|
||||
use anyhow::{Context, Result, anyhow, bail};
|
||||
use mlua::{FromLua, Lua, StdLib, Table, Value};
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
@@ -17,13 +17,13 @@ pub struct LuaRuntime {
|
||||
|
||||
impl LuaRuntime {
|
||||
/// 初始化限定权限的 Lua 沙箱环境
|
||||
pub fn new(layout: &ShimLayout) -> Result<Self, ShimError> {
|
||||
pub fn new(layout: &ShimLayout) -> Result<Self> {
|
||||
// 只加载安全的标准库,剥离 os / io 等风险模块
|
||||
let lua = Lua::new_with(
|
||||
StdLib::TABLE | StdLib::STRING | StdLib::MATH | StdLib::PACKAGE,
|
||||
mlua::LuaOptions::default(),
|
||||
)
|
||||
.map_err(|e| ShimError::Environment(format!("初始化 Lua 失败: {}", e)))?;
|
||||
.context("初始化 Lua 失败")?;
|
||||
|
||||
let globals = lua.globals();
|
||||
|
||||
@@ -34,7 +34,7 @@ impl LuaRuntime {
|
||||
// 1. 注入锚点变量 __SHIM_DIR__(shim 安装根目录)
|
||||
globals
|
||||
.set("__SHIM_DIR__", root_dir.clone())
|
||||
.map_err(|e| ShimError::Environment(e.to_string()))?;
|
||||
.context("设置 __SHIM_DIR__ 环境变量失败")?;
|
||||
|
||||
// 2. 安全暴露 get_env 供配置读取环境变量
|
||||
// 返回按平台路径分隔符拆分后的段数组(自动剥离引号包裹),
|
||||
@@ -68,11 +68,11 @@ impl LuaRuntime {
|
||||
|
||||
Ok(table)
|
||||
})
|
||||
.map_err(|e| ShimError::Environment(e.to_string()))?;
|
||||
.context("注册 get_env 函数失败")?;
|
||||
|
||||
globals
|
||||
.set("get_env", get_env)
|
||||
.map_err(|e| ShimError::Environment(e.to_string()))?;
|
||||
.context("挂载 get_env 全局函数失败")?;
|
||||
|
||||
// 3. 配置 package.path,确保 require 行为正常
|
||||
if let Ok(package) = globals.get::<Table>("package") {
|
||||
@@ -92,10 +92,10 @@ impl LuaRuntime {
|
||||
// 而不是让整个 shims.lua 解析失败(排查问题时日志可见)
|
||||
let original_require: mlua::Function = globals
|
||||
.get("require")
|
||||
.map_err(|e| ShimError::Environment(format!("获取 require 失败: {}", e)))?;
|
||||
.context("获取内置 require 函数失败")?;
|
||||
globals
|
||||
.set("_rshim_original_require", &original_require)
|
||||
.map_err(|e| ShimError::Environment(e.to_string()))?;
|
||||
.context("备份原始 require 函数失败")?;
|
||||
|
||||
let wrapped_require = lua
|
||||
.create_function(|lua, module: String| -> mlua::Result<Value> {
|
||||
@@ -112,26 +112,27 @@ impl LuaRuntime {
|
||||
}
|
||||
}
|
||||
})
|
||||
.map_err(|e| ShimError::Environment(e.to_string()))?;
|
||||
.context("创建包装版 require 函数失败")?;
|
||||
|
||||
globals
|
||||
.set("require", wrapped_require)
|
||||
.map_err(|e| ShimError::Environment(e.to_string()))?;
|
||||
.context("重载 require 函数失败")?;
|
||||
|
||||
Ok(Self { lua })
|
||||
}
|
||||
|
||||
/// 执行指定脚本文件,直接返回完整的 Lua Table
|
||||
pub fn eval_script<T: FromLua>(&self, path: impl AsRef<Path>) -> Result<T, ShimError> {
|
||||
pub fn eval_script<T: FromLua>(&self, path: impl AsRef<Path>) -> Result<T> {
|
||||
let path = path.as_ref();
|
||||
// println!("path {:?}", path);
|
||||
let bytes = fs::read(path)?;
|
||||
let code = String::from_utf8(bytes).map_err(|e| {
|
||||
ShimError::InvalidConfig(format!(
|
||||
"{} 不是有效的 UTF-8 文件(请将 Lua 配置文件保存为 UTF-8 编码): {}",
|
||||
path.display(),
|
||||
e.utf8_error()
|
||||
))
|
||||
let bytes =
|
||||
fs::read(path).with_context(|| format!("无法读取配置文件: {}", path.display()))?;
|
||||
|
||||
let code = String::from_utf8(bytes).with_context(|| {
|
||||
format!(
|
||||
"{} 不是有效的 UTF-8 文件(请将 Lua 配置文件保存为 UTF-8 编码)",
|
||||
path.display()
|
||||
)
|
||||
})?;
|
||||
println!("code {:?}", code);
|
||||
let chunk_name = format!("@{}", path.display());
|
||||
@@ -140,15 +141,13 @@ impl LuaRuntime {
|
||||
.load(&code)
|
||||
.set_name(&chunk_name)
|
||||
.eval::<T>()
|
||||
.map_err(|e| ShimError::LuaExecution {
|
||||
file: path.display().to_string(),
|
||||
source: e,
|
||||
})
|
||||
// .map_err(|e| anyhow!(e.to_string()))
|
||||
.with_context(|| format!("执行 Lua 配置文件失败: {}", path.display()))
|
||||
}
|
||||
|
||||
// /// 将 Lua Value 解析转化为 ShimConfig 数据对象
|
||||
// pub fn parse_config(&self, value: Value) -> Result<ShimConfig, ShimError> {
|
||||
// ShimConfig::from_lua(value, &self.lua).map_err(|e| ShimError::InvalidConfig(e.to_string()))
|
||||
// pub fn parse_config(&self, value: Value) -> Result<ShimConfig, Error> {
|
||||
// ShimConfig::from_lua(value, &self.lua).map_err(|e| Error::InvalidConfig(e.to_string()))
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user