aboutsummaryrefslogtreecommitdiffstats
path: root/src/theming/lua.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/theming/lua.rs')
-rw-r--r--src/theming/lua.rs45
1 files changed, 35 insertions, 10 deletions
diff --git a/src/theming/lua.rs b/src/theming/lua.rs
index 6bd6989..0699f09 100644
--- a/src/theming/lua.rs
+++ b/src/theming/lua.rs
@@ -18,7 +18,7 @@ static LUA: LazyLock<Mutex<Lua>> = LazyLock::new(|| {
lua.sandbox(true).expect("lua initialization");
lua.set_compiler(
- if CONFIG.theme_debug { Compiler::new().set_optimization_level(0).set_debug_level(2) }
+ if CONFIG.theme_dev { Compiler::new().set_optimization_level(0).set_debug_level(2) }
else { Compiler::new().set_optimization_level(2).set_debug_level(1) }
);
@@ -38,14 +38,19 @@ static LUA: LazyLock<Mutex<Lua>> = LazyLock::new(|| {
for (k, v) in INTERNAL_THEMES {
log::info!("Registering compiled lua theme `{k}`.");
- let _ = themes.set(*k, lua.load(*v).into_function().expect("loading internal theme"));
+ let _ = themes.set(*k, lua.load(*v).eval::<Value>().expect("loading internal theme"));
}
if let Some(theme_dir) = CONFIG.theme_dir.as_ref() {
- log::info!("Registering lua theme dir `{theme_dir}` with extension `{}`.", CONFIG.theme_ext_lua);
- for (k, v) in walk_dir(theme_dir.as_ref().as_ref()).expect("walking theme dir") {
- log::info!("Registering runtime lua theme `{k}`.");
- let _ = themes.set(k, lua.load(v).eval::<Value>().expect("loading internal theme"));
+ if !CONFIG.theme_dev {
+ log::info!("Registering lua theme dir `{theme_dir}` with extension `{}`.", CONFIG.theme_ext_lua);
+ for (k, v) in walk_dir(theme_dir.as_ref().as_ref()).expect("walking theme dir") {
+ log::info!("Registering runtime lua theme `{k}`.");
+ let _ = themes.set(k, lua.load(v).eval::<Value>().expect("loading external theme"));
+ }
+ }
+ else {
+ log::info!("Ready to dev-load lua themes from `{theme_dir}` with extension `{}`.", CONFIG.theme_ext_lua);
}
}
@@ -86,13 +91,29 @@ fn walk_dir(path: &Path) -> std::io::Result<Vec<(String, String)>> {
}
pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option<Result<String, StatusCode>> {
+ if name == ".." || name.starts_with("../") || name.ends_with("/..") || name.contains("/../") {
+ return Some(Err(StatusCode::BAD_REQUEST))
+ }
+
LUA.clear_poison();
let lua = LUA.lock().expect("FIXME: Mutex poisoning race condition.");
let themes: Table = lua.globals().get("__themes").unwrap();
- let Ok(Value::Function(theme)) = themes.get(name)
- else {
- return None;
- };
+ let theme;
+ match themes.get(name) {
+ Ok(Value::Function(themefn)) => { theme = themefn; },
+ Ok(Value::Nil) if !CONFIG.theme_dev || CONFIG.theme_dir.is_none() => { return None; },
+ Ok(Value::Nil) => {
+ let code = fs::read_to_string(CONFIG.theme_dir.as_ref().unwrap().to_string() + "/" + name + &CONFIG.theme_ext_lua).ok()?;
+ let res = lua.load(code).eval::<Value>();
+ match res {
+ Ok(Value::Function(themefn)) => { theme = themefn; },
+ Ok(v) => { log::error!("Got `{v:?}` instead of Function when dev-loading `{name}`."); return Some(Err(StatusCode::INTERNAL_SERVER_ERROR)); },
+ Err(e) => { log::error!("Error dev-loading `{name}`: {e}"); return Some(Err(StatusCode::INTERNAL_SERVER_ERROR)); },
+ }
+ },
+ Ok(v) => { log::error!("Got `{v:?}` instead of Function when loading `{name}`."); return Some(Err(StatusCode::INTERNAL_SERVER_ERROR)); }
+ Err(e) => { log::error!("Error loading `{name}`: {e}"); return Some(Err(StatusCode::INTERNAL_SERVER_ERROR)); }, //TODO: gate behind flag
+ }
let ctx = match lua.to_value(ctx) {
Ok(ok) => ok,
@@ -104,3 +125,7 @@ pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option<Result<String,
Some(theme.call((ctx,)).map_err(|e| { log::error!("Lua theme execution error: {e}"); StatusCode::INTERNAL_SERVER_ERROR }))
}
+
+pub fn touch() {
+ LazyLock::force(&LUA);
+}