diff options
| author | John Turner <jturner.usa@gmail.com> | 2026-03-05 03:19:25 -0500 |
|---|---|---|
| committer | John Turner <jturner.usa@gmail.com> | 2026-03-05 03:19:25 -0500 |
| commit | 54a5e893bc4255f833c9ded1f0c853a977e004d5 (patch) | |
| tree | f7a21837f2a2e5a26df956fca72352c36dcee4ea /src | |
| parent | cb6f70f6908aaea46c5d6332d3deb9a4a83733aa (diff) | |
| download | httpd-54a5e893bc4255f833c9ded1f0c853a977e004d5.tar.gz | |
add function to join paths together safely and provide them to lua
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/main.rs b/src/main.rs index 6d89a0d..f3ba157 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,11 @@ #![allow(dead_code)] -use std::process::ExitCode; +use std::{ + ffi::OsString, + os::unix::ffi::OsStringExt, + path::{Component, Path, PathBuf}, + process::ExitCode, +}; use mlua::{Function, Lua, Table}; @@ -57,6 +62,9 @@ enum InitLuaError { #[error("failed to create variable: {0}")] CreateTable(mlua::Error), + #[error("failed to create helper function: {0}")] + Function(mlua::Error), + #[error("failed to set variable {1}: {0}")] SetVar(mlua::Error, String), @@ -119,6 +127,17 @@ async fn response(handlers: Table, stream: TcpStream) -> Result<(), ResponseErro Ok(()) } +fn join_path(root: &Path, rest: &Path) -> Result<PathBuf, std::io::Error> { + root.components() + .chain( + rest.components() + .filter(|p| !matches!(p, Component::RootDir)), + ) + .filter(|p| !matches!(p, Component::CurDir | Component::ParentDir)) + .collect::<PathBuf>() + .canonicalize() +} + fn init_lua(lua: Lua) -> Result<(), InitLuaError> { let http = lua.create_table().map_err(InitLuaError::CreateTable)?; @@ -126,6 +145,18 @@ fn init_lua(lua: Lua) -> Result<(), InitLuaError> { .set("http", http.clone()) .map_err(|e| InitLuaError::SetVar(e, "http".to_string()))?; + http.set( + "join_paths", + lua.create_function(|_, (root, rest): (mlua::String, mlua::String)| { + let a = PathBuf::from(OsString::from_vec(root.as_bytes().to_vec())); + let b = PathBuf::from(OsString::from_vec(rest.as_bytes().to_vec())); + + join_path(&a, &b).map_err(|e| mlua::Error::runtime(format!("failed to join path: {e}"))) + }) + .map_err(InitLuaError::Function)?, + ) + .map_err(|e| InitLuaError::SetVar(e, "http.join_paths".to_string()))?; + let chunk = lua.load(std::fs::read_to_string("config.lua").map_err(InitLuaError::LoadConfig)?); chunk.eval::<()>().map_err(InitLuaError::EvalConfig)?; |
