mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-12 08:51:11 +00:00
Merge pull request #2112 from Silvertree2010/fix/h10143-file-export-exports-the-whole-pa
Reject invalid layer ids in file.export and file.exportLayers
This commit is contained in:
2 files changed
+28
-3
No files matched your search
@@ -1,7 +1,7 @@
|
||||
use super::load::{ext, write};
|
||||
use super::save::thumbnail;
|
||||
use super::*;
|
||||
use crate::params::f64_of;
|
||||
use crate::params::{f64_of, req_targets};
|
||||
|
||||
/// Encode `ids` (or the page) in `format` at `scale`.
|
||||
pub fn export_bytes(doc: &Document, ids: &[NodeId], format: ExportFormat, scale: f64) -> Result<Vec<u8>> {
|
||||
@@ -86,7 +86,7 @@ pub(super) fn export(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
_ => {}
|
||||
}
|
||||
let doc = s.doc()?;
|
||||
let mut ids = targets(s, p);
|
||||
let mut ids = export_targets(cmd, s, p)?;
|
||||
if ids.is_empty() {
|
||||
ids = doc.get(s.page()?)?.children.clone();
|
||||
}
|
||||
@@ -325,11 +325,22 @@ pub fn exportable_layers(doc: &Document, page: NodeId) -> Vec<NodeId> {
|
||||
doc.subtree(page).into_iter().skip(1).filter(|i| doc.node(*i).is_some_and(|n| !n.exports.is_empty())).collect()
|
||||
}
|
||||
|
||||
/// Named layers (`ids` / `id`), checked like other commands; empty when none are named, so the
|
||||
/// caller can fall back to its default instead of silently dropping a bad id.
|
||||
fn export_targets(cmd: &str, s: &Session, p: &Value) -> Result<Vec<NodeId>> {
|
||||
let named = match get(p, "ids") {
|
||||
Some(Value::Array(a)) if !a.is_empty() => true,
|
||||
Some(Value::Array(_) | Value::Null) | None => get(p, "id").is_some_and(|v| !v.is_null()),
|
||||
Some(_) => true,
|
||||
};
|
||||
if named { req_targets(cmd, s, p) } else { Ok(targets(s, p)) }
|
||||
}
|
||||
|
||||
pub(super) fn export_layers(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let cmd = "file.exportLayers";
|
||||
let doc = s.doc()?;
|
||||
let assets = boolean(p, "assets").unwrap_or(false);
|
||||
let mut ids = targets(s, p);
|
||||
let mut ids = export_targets(cmd, s, p)?;
|
||||
if ids.is_empty() {
|
||||
ids = if assets { vec![s.page()?] } else { exportable_layers(doc, s.page()?) };
|
||||
}
|
||||
|
||||
@@ -384,3 +384,17 @@ fn copy_as_png_svg_and_code() {
|
||||
let css = crate::codegen::code_for(doc, a, crate::codegen::CodeLang::Css);
|
||||
assert!(css.contains("background: #FF0000;"), "Copy as CSS is the layer's CSS from Inspect");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn export_rejects_an_invalid_layer_id_instead_of_exporting_the_page() {
|
||||
let mut s = Session::new();
|
||||
let r = rect(&mut s, 0.0, 0.0, 10.0, 10.0, "#ff0000", None);
|
||||
ex(&mut s, "export.add", json!({"ids": [r]}));
|
||||
for cmd in ["file.export", "file.exportLayers"] {
|
||||
for p in [json!({"ids": ["abc"], "format": "svg"}), json!({"id": "abc", "format": "svg"}), json!({"ids": [], "id": "abc", "format": "svg"})] {
|
||||
let res = s.execute(cmd, &p);
|
||||
assert!(res.is_err(), "{cmd} {p} exported for an invalid id: {res:?}");
|
||||
}
|
||||
}
|
||||
assert!(s.execute("file.export", &json!({"format": "svg"})).is_ok());
|
||||
}
|
||||
Reference in new issue
Block a user