mirror of
https://github.com/extism/extism.git
synced 2026-01-11 14:58:01 -05:00
Compare commits
5 Commits
fix-clippy
...
allowed-pa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fad7eb4454 | ||
|
|
37e0e2fed4 | ||
|
|
5b94feb7ec | ||
|
|
6146d2f47c | ||
|
|
424e6c328a |
@@ -1,6 +1,10 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
mod local_path;
|
||||
|
||||
pub use local_path::LocalPath;
|
||||
|
||||
#[deprecated]
|
||||
pub type ManifestMemory = MemoryOptions;
|
||||
|
||||
@@ -279,7 +283,7 @@ pub struct Manifest {
|
||||
/// the path on disk to the path it should be available inside the plugin.
|
||||
/// For example, `".": "/tmp"` would mount the current directory as `/tmp` inside the module
|
||||
#[serde(default)]
|
||||
pub allowed_paths: Option<BTreeMap<String, PathBuf>>,
|
||||
pub allowed_paths: Option<BTreeMap<PathBuf, LocalPath>>,
|
||||
|
||||
/// The plugin timeout in milliseconds
|
||||
#[serde(default)]
|
||||
@@ -337,15 +341,15 @@ impl Manifest {
|
||||
}
|
||||
|
||||
/// Add a path to `allowed_paths`
|
||||
pub fn with_allowed_path(mut self, src: String, dest: impl AsRef<Path>) -> Self {
|
||||
pub fn with_allowed_path(mut self, src: impl Into<LocalPath>, dest: impl AsRef<Path>) -> Self {
|
||||
let dest = dest.as_ref().to_path_buf();
|
||||
match &mut self.allowed_paths {
|
||||
Some(p) => {
|
||||
p.insert(src, dest);
|
||||
p.insert(dest, src.into());
|
||||
}
|
||||
None => {
|
||||
let mut p = BTreeMap::new();
|
||||
p.insert(src, dest);
|
||||
p.insert(dest, src.into());
|
||||
self.allowed_paths = Some(p);
|
||||
}
|
||||
}
|
||||
@@ -354,8 +358,8 @@ impl Manifest {
|
||||
}
|
||||
|
||||
/// Set `allowed_paths`
|
||||
pub fn with_allowed_paths(mut self, paths: impl Iterator<Item = (String, PathBuf)>) -> Self {
|
||||
self.allowed_paths = Some(paths.collect());
|
||||
pub fn with_allowed_paths(mut self, paths: impl Iterator<Item = (LocalPath, PathBuf)>) -> Self {
|
||||
self.allowed_paths = Some(paths.map(|(local, wasm)| (wasm, local)).collect());
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
119
manifest/src/local_path.rs
Normal file
119
manifest/src/local_path.rs
Normal file
@@ -0,0 +1,119 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
|
||||
pub enum LocalPath {
|
||||
ReadOnly(PathBuf),
|
||||
ReadWrite(PathBuf),
|
||||
}
|
||||
|
||||
impl LocalPath {
|
||||
pub fn as_path(&self) -> &Path {
|
||||
match self {
|
||||
LocalPath::ReadOnly(p) => p.as_path(),
|
||||
LocalPath::ReadWrite(p) => p.as_path(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for LocalPath {
|
||||
fn from(value: &str) -> Self {
|
||||
if let Some(s) = value.strip_prefix("ro:") {
|
||||
LocalPath::ReadOnly(PathBuf::from(s))
|
||||
} else {
|
||||
LocalPath::ReadWrite(PathBuf::from(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for LocalPath {
|
||||
fn from(value: String) -> Self {
|
||||
LocalPath::from(value.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PathBuf> for LocalPath {
|
||||
fn from(value: PathBuf) -> Self {
|
||||
LocalPath::ReadWrite(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Path> for LocalPath {
|
||||
fn from(value: &Path) -> Self {
|
||||
LocalPath::ReadWrite(value.to_path_buf())
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for LocalPath {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
match self {
|
||||
LocalPath::ReadOnly(path) => {
|
||||
let s = match path.to_str() {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return Err(serde::ser::Error::custom(
|
||||
"Path contains invalid UTF-8 characters",
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
format!("ro:{s}").serialize(serializer)
|
||||
}
|
||||
LocalPath::ReadWrite(path) => path.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LocalPathVisitor;
|
||||
|
||||
impl serde::de::Visitor<'_> for LocalPathVisitor {
|
||||
type Value = LocalPath;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("path string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(From::from(v))
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(From::from(v))
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
std::str::from_utf8(v)
|
||||
.map(From::from)
|
||||
.map_err(|_| serde::de::Error::invalid_value(serde::de::Unexpected::Bytes(v), &self))
|
||||
}
|
||||
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
String::from_utf8(v).map(From::from).map_err(|e| {
|
||||
serde::de::Error::invalid_value(serde::de::Unexpected::Bytes(&e.into_bytes()), &self)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for LocalPath {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::de::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_string(LocalPathVisitor)
|
||||
}
|
||||
}
|
||||
@@ -352,9 +352,9 @@ impl CurrentPlugin {
|
||||
|
||||
if let Some(a) = &manifest.allowed_paths {
|
||||
for (k, v) in a.iter() {
|
||||
let readonly = k.starts_with("ro:");
|
||||
let readonly = matches!(v, extism_manifest::LocalPath::ReadOnly(_));
|
||||
|
||||
let dir_path = if readonly { &k[3..] } else { k };
|
||||
let dir_path = v.as_path();
|
||||
|
||||
let dir = wasi_common::sync::dir::Dir::from_cap_std(
|
||||
wasi_common::sync::Dir::open_ambient_dir(dir_path, auth)?,
|
||||
@@ -366,7 +366,7 @@ impl CurrentPlugin {
|
||||
Box::new(dir)
|
||||
};
|
||||
|
||||
ctx.push_preopened_dir(file, v)?;
|
||||
ctx.push_preopened_dir(file, k)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user