use crate::parse::Token;
use crate::registry;
use crate::verdict::Verdict;
pub fn is_safe_magick(tokens: &[Token]) -> Verdict {
if tokens[1..].iter().any(|t| t.as_str() == "-script") {
return Verdict::Denied;
}
if let Some(verdict) = registry::try_sub_dispatch("magick", tokens) {
return verdict;
}
if let Some(v @ Verdict::Allowed(_)) = registry::try_fallback_grammar("magick", tokens) {
return v;
}
let first = tokens[1].as_str();
let leading_flag = first.starts_with('-') && first != "-";
if !leading_flag && !crate::policy::looks_like_path(first) {
return Verdict::Denied;
}
let inner = shell_words::join(
std::iter::once("convert").chain(tokens[1..].iter().map(|t| t.as_str())),
);
crate::command_verdict(&inner)
}
#[cfg(test)]
mod tests {
use crate::is_safe_command;
use crate::verdict::{SafetyLevel, Verdict};
fn check(cmd: &str) -> bool {
is_safe_command(cmd)
}
fn verdict(cmd: &str) -> Verdict {
crate::command_verdict(cmd)
}
safe! {
magick_help: "magick --help",
magick_version: "magick --version",
magick_convert_explicit: "magick convert in.png out.png",
magick_convert_resize: "magick convert in.png -resize 1200x out.png",
magick_identify_explicit: "magick identify photo.jpg",
magick_implicit_convert: "magick in.png out.png",
magick_implicit_with_resize: "magick in.png -resize 1200x out.png",
magick_implicit_avif_to_png: "magick /Users/me/Downloads/x.avif -resize 1200x /tmp/out.png",
magick_implicit_with_quality: "magick in.jpg -quality 85 out.jpg",
magick_mogrify: "magick mogrify -resize 50% photo.jpg",
magick_compare: "magick compare a.png b.png diff.png",
magick_montage: "magick montage *.png montage.png",
magick_combine: "magick combine a.png b.png combined.png",
magick_stream: "magick stream image.png pixels.gray",
magick_implicit_list_font: "magick -list font",
magick_implicit_list_color: "magick -list color",
magick_implicit_leading_resize: "magick -resize 1200x in.png out.png",
magick_implicit_leading_quality: "magick -quality 85 in.jpg out.jpg",
}
denied! {
magick_conjure_msl: "magick conjure script.msl",
magick_display_window: "magick display photo.jpg",
magick_animate_gif: "magick animate animation.gif",
magick_import_screen: "magick import screen.png",
magick_script_flag: "magick -script attack.msl",
magick_script_after_input: "magick in.png -script attack.msl out.png",
magick_convert_with_script: "magick convert -script attack.msl",
}
#[test]
fn magick_implicit_is_safewrite() {
assert_eq!(
verdict("magick in.png -resize 1200x out.png"),
Verdict::Allowed(SafetyLevel::SafeWrite),
);
}
#[test]
fn magick_identify_routes_through_identify_top_level() {
assert_eq!(
verdict("magick identify photo.jpg"),
Verdict::Allowed(SafetyLevel::Inert),
);
}
#[test]
fn magick_help_is_inert() {
assert_eq!(
verdict("magick --help"),
Verdict::Allowed(SafetyLevel::Inert),
);
}
}