#1009: data.fill refused before it copies or writes in a read-only live file

This commit is contained in:
bflatastic
2026-10-24 13:01:55 +07:00
parent 35fada1161
commit a7b7dfe1c4
2 changed files with 12 additions and 1 deletions
+5 -1
View File
@@ -8,7 +8,7 @@ use serde_json::{Value, json};
use crate::cmd::CommandSpec;
use crate::params::{get, id, id_of, num_or, string};
use crate::{Result, Session, bad, spec};
use crate::{EngineError, Result, Session, bad, spec};
const CMD: &str = "data.fill";
const MAX_ROWS: usize = 500;
@@ -31,6 +31,10 @@ fn file_name(name: &str) -> String {
}
fn fill(s: &mut Session, p: &Value) -> Result<Value> {
// Refused before any copy or file is made: a rollback afterwards wouldn't take files back.
if let Some(why) = s.live_read_only(s.ds()?.uid) {
return Err(EngineError::Disabled(CMD.into(), why.into()));
}
let src = id(p, "id").ok_or_else(|| bad(CMD, "`id` (the frame to repeat) required"))?;
let rows = match get(p, "rows") {
Some(Value::Array(a)) if a.iter().all(Value::is_object) && a.len() <= MAX_ROWS => a.clone(),
+7
View File
@@ -105,6 +105,13 @@ fn a_view_link_makes_the_file_read_only() {
refused(&mut s, "shape.rectangle", json!({"x": 0, "y": 0, "width": 5, "height": 5}), VIEW_ONLY);
refused(&mut s, "node.set", json!({"ids": [card.0], "props": {"name": "Mine"}}), VIEW_ONLY);
refused(&mut s, "edit.delete", json!({"ids": [card.0]}), VIEW_ONLY);
// Refused before it makes copies or writes files, which no rollback takes back.
let dir = std::env::temp_dir().join(format!("figcraft-view-fill-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
refused(&mut s, "data.fill", json!({"id": card.0, "rows": [{"name": "Copy"}], "dir": dir.to_string_lossy()}), VIEW_ONLY);
assert_eq!(std::fs::read_dir(&dir).unwrap().count(), 0, "no file was written");
let _ = std::fs::remove_dir_all(&dir);
refused(&mut s, "tool.set", json!({"tool": "text"}), VIEW_ONLY);
assert!(matches!(s.begin_interaction("Move"), Err(EngineError::Disabled(..))));
assert_eq!(*s.doc().unwrap(), before);