diff --git a/crates/engine/src/cmd/swatchlib.rs b/crates/engine/src/cmd/swatchlib.rs index f88130763..b7a0e2f29 100644 --- a/crates/engine/src/cmd/swatchlib.rs +++ b/crates/engine/src/cmd/swatchlib.rs @@ -232,13 +232,16 @@ impl Libraries { /// others are listed as loaded until the app quits. pub(crate) fn load(&mut self, p: &Value, cmd: &str, parse: impl FnOnce(&[u8], &str) -> Result) -> Result<(LibraryInfo, Arc)> { let path = text_param(p, "path", cmd)?; - let bytes = match (path, text_param(p, "data", cmd)?, text_param(p, "dataBase64", cmd)?) { + let data = text_param(p, "data", cmd)?; + let data_base64 = text_param(p, "dataBase64", cmd)?; + let name = text_param(p, "name", cmd)?; + let bytes = match (path, data, data_base64) { (Some(path), ..) => read_file(path)?, (None, Some(text), _) => text.as_bytes().to_vec(), (None, None, Some(b64)) => vectorcraft_format::base64_decode(b64).ok_or_else(|| bad(cmd, "bad dataBase64"))?, _ => return Err(bad(cmd, "give `path`, `data` or `dataBase64`")), }; - let file = text_param(p, "name", cmd)?.map(str::to_string).or_else(|| path.map(file_name)).unwrap_or_else(|| "Library".into()); + let file = name.map(str::to_string).or_else(|| path.map(file_name)).unwrap_or_else(|| "Library".into()); let lib = parse(&bytes, &file)?; self.rescan(); let user = diff --git a/crates/engine/src/tests/swatchlib.rs b/crates/engine/src/tests/swatchlib.rs index 7e3e8d616..c20968db5 100644 --- a/crates/engine/src/tests/swatchlib.rs +++ b/crates/engine/src/tests/swatchlib.rs @@ -215,6 +215,22 @@ fn library_commands_refuse_params_of_the_wrong_form() { assert!(r["added"].as_array().is_some_and(|a| !a.is_empty()), "{r}"); } +#[test] +fn library_loads_validate_name_before_reading_a_file_or_decoding_data() { + let mut s = session(); + let missing = temp_dir("invalid-load-name").join("missing.vcswatches").to_string_lossy().to_string(); + for cmd in ["swatch.library.load", "graphicStyle.loadLibrary", "symbol.loadLibrary", "brush.loadLibrary"] { + for name in [json!(5), json!([])] { + let p = json!({"path": missing, "name": name}); + let e = s.execute(cmd, &p).unwrap_err().to_string(); + assert!(e.contains("`name` must be a string"), "{cmd} {p}: {e}"); + } + let p = json!({"dataBase64": "not base64!", "name": 5}); + let e = s.execute(cmd, &p).unwrap_err().to_string(); + assert!(e.contains("`name` must be a string"), "{cmd} {p}: {e}"); + } +} + #[test] fn libraries_saved_in_the_user_folder_are_user_defined() { let dir = temp_dir("user");