diff options
Diffstat (limited to 'src/theming')
-rw-r--r-- | src/theming/hbs.rs | 6 | ||||
-rw-r--r-- | src/theming/lua.rs | 45 |
2 files changed, 40 insertions, 11 deletions
diff --git a/src/theming/hbs.rs b/src/theming/hbs.rs index 67a2ae4..398715a 100644 --- a/src/theming/hbs.rs +++ b/src/theming/hbs.rs @@ -18,7 +18,7 @@ static HANDLEBARS: LazyLock<Handlebars> = LazyLock::new(|| { log::info!("Registering internal handlebars theme `{key}`"); hb.register_template_string(key, fulltext).unwrap(); } - hb.set_dev_mode(CONFIG.theme_debug); + hb.set_dev_mode(CONFIG.theme_dev); if let Some(themes_dir) = CONFIG.theme_dir.as_ref() { log::info!("Registering handlebars theme dir `{themes_dir}` with extension `{}`.", CONFIG.theme_ext_hbs); @@ -34,3 +34,7 @@ pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option<Result<String, let render = templ.renders(&HANDLEBARS, &ctx, &mut RenderContext::new(Some(&name.into()))).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR); Some(render) } + +pub fn touch() { + LazyLock::force(&HANDLEBARS); +} 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); +} |