mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 05:37:23 -06:00
Libraries: library loads check name before reading the file
swatch.library.load, graphicStyle.loadLibrary, symbol.loadLibrary and brush.loadLibrary read the whole file or decoded data before checking `name`, so a call with a `name` that is not a string read the file first, and with a missing file reported the file error instead of the parameter error. The shared loader now checks every parameter before it reads anything.
This commit is contained in:
@@ -232,13 +232,16 @@ impl<L: LibraryFile> Libraries<L> {
|
||||
/// 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<L>) -> Result<(LibraryInfo, Arc<L>)> {
|
||||
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 =
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user