MCP: an agent's folders hold for file loads through the app and for a design's font files (#1112)

doc.open and the STEP/mesh imports run on the file loader's worker with the request's path scope, and a font named by file path in a design is checked against the scope before it is read.
This commit is contained in:
Mateusz Sych authored and GitHub committed 2026-10-14 13:58:56 -04:00
1 parent 6de8f6db95
commit c469adf456
8 files changed
+122 -30

No files matched your search

+29
View File
@@ -64,3 +64,32 @@ fn file_commands_stay_inside_the_agents_folders() {
s.execute("file.export", &json!({"path": at(&out, "x.stl")})).unwrap();
let _ = std::fs::remove_dir_all(&base);
}
/// A design names the font file of its text, and opening it reads that file: for an agent, a
/// font outside its folders stays unread, even one already read (and cached) for the user.
#[test]
fn a_designs_font_file_stays_inside_the_agents_folders() {
let base = solidcraft_io::vfs::temp_dir().join(format!("solidcraft-font-scope-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&base);
let (root, out) = (base.join("root"), base.join("out"));
std::fs::create_dir_all(&root).unwrap();
std::fs::create_dir_all(&out).unwrap();
let font = out.join("f.ttf");
std::fs::write(&font, solidcraft_sketch::font_data(None).unwrap().bytes()).unwrap();
let mut s = Session::default();
s.execute("sketch.create", &json!({"plane": "XY"})).unwrap();
s.execute("sketch.text", &json!({"text": "A", "at": [0, 0], "font": font.to_string_lossy()})).unwrap();
s.execute("sketch.finish", &json!({})).unwrap();
let design = root.join("text.solidcraft");
std::fs::write(&design, solidcraft_io::write_design(&s.doc)).unwrap();
let open = json!({"path": design.to_string_lossy()});
// The sketch's warning says what its text couldn't read.
let warnings = |s: &Session| s.model.results.iter().filter_map(|r| r.warning.clone()).collect::<Vec<_>>().join("; ");
s.execute("doc.open", &open).unwrap();
assert!(warnings(&s).is_empty(), "the user's own open reads it: {}", warnings(&s));
scoped(Some(PathScope::new([root.clone()])), || {
s.execute("doc.open", &open).unwrap();
assert!(warnings(&s).contains("outside the folders this agent may use"), "{}", warnings(&s));
});
let _ = std::fs::remove_dir_all(&base);
}