mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 17:40:14 -06:00
Merge pull request #5305 from storytold/fix/sec-export-settings-no-passwords
Export for Screens: keep PDF passwords out of remembered settings
This commit is contained in:
@@ -698,6 +698,8 @@ fn preset_settings(s: &Session, cmd: &str, given: &Map<String, Value>) -> Result
|
||||
// Refuse what an export would refuse, now rather than when the preset is used.
|
||||
check_settings(s, &Value::Object(settings.clone())).map_err(|e| bad(cmd, e.to_string()))?;
|
||||
Folders::of(&ScreenParams::of(&Value::Object(settings.clone()))?).map_err(|e| bad(cmd, e.to_string()))?;
|
||||
let mut settings = settings;
|
||||
remove_passwords(&mut settings);
|
||||
Ok(settings)
|
||||
}
|
||||
|
||||
@@ -1275,9 +1277,33 @@ fn remember(s: &mut Session, p: &Value) {
|
||||
let _ = store_settings(s, settings);
|
||||
}
|
||||
|
||||
/// The PDF passwords an export may be given (`security` of a PDF row or of `settings.pdf`).
|
||||
const PASSWORD_KEYS: [&str; 2] = ["openPassword", "permissionsPassword"];
|
||||
|
||||
/// `settings` without the PDF passwords anywhere in them: settings kept in the document (which
|
||||
/// native saves write) or in the preferences hold the export's choices, never its secrets, as
|
||||
/// the PDF settings themselves are saved without them.
|
||||
fn remove_passwords(settings: &mut Map<String, Value>) {
|
||||
for key in PASSWORD_KEYS {
|
||||
settings.remove(key);
|
||||
}
|
||||
for v in settings.values_mut() {
|
||||
remove_passwords_in(v);
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_passwords_in(v: &mut Value) {
|
||||
match v {
|
||||
Value::Object(m) => remove_passwords(m),
|
||||
Value::Array(items) => items.iter_mut().for_each(remove_passwords_in),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Make `settings` the document's export settings. Not an undo step (like the settings of any
|
||||
/// export); the document has changed only if they differ.
|
||||
pub(crate) fn store_settings(s: &mut Session, settings: Map<String, Value>) -> Result<()> {
|
||||
pub(crate) fn store_settings(s: &mut Session, mut settings: Map<String, Value>) -> Result<()> {
|
||||
remove_passwords(&mut settings);
|
||||
let st = s.doc_mut()?;
|
||||
if st.doc.export_settings != settings {
|
||||
Arc::make_mut(&mut st.doc).export_settings = settings;
|
||||
@@ -1334,4 +1360,21 @@ mod tests {
|
||||
assert_eq!(safe_file_name("lpt9 .png"), "lpt9-.png");
|
||||
assert_eq!(safe_file_name("My CON .png"), "My CON .png");
|
||||
}
|
||||
|
||||
/// The settings an export leaves in the document keep its PDF security choices but not its
|
||||
/// passwords, in a row or in `settings.pdf`.
|
||||
#[test]
|
||||
fn stored_settings_leave_out_pdf_passwords() {
|
||||
let mut s = crate::Session::new();
|
||||
s.execute("file.new", &serde_json::json!({"width": 100, "height": 100})).unwrap();
|
||||
let given = serde_json::json!({
|
||||
"formats": [{"format": "pdf", "security": {"openPassword": "open sesame", "permissionsPassword": "owner", "printing": "low"}}],
|
||||
"settings": {"pdf": {"security": {"openPassword": "open sesame", "copy": false}}},
|
||||
});
|
||||
super::store_settings(&mut s, given.as_object().unwrap().clone()).unwrap();
|
||||
let kept = serde_json::Value::Object(s.doc().unwrap().doc.export_settings.clone());
|
||||
assert!(!kept.to_string().contains("Password"), "{kept}");
|
||||
assert_eq!(kept["formats"][0]["security"]["printing"], "low");
|
||||
assert_eq!(kept["settings"]["pdf"]["security"]["copy"], false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user