Merge pull request #5377 from storytold/fix/sec-placed-art-no-stale-full-read

Placed documents: a refused read shows the preview, not another caller's cached full read
This commit is contained in:
BFlat
2026-11-03 22:39:15 +07:00
committed by GitHub
2 changed files with 27 additions and 0 deletions
+3
View File
@@ -559,6 +559,9 @@ impl Document {
reads += usize::from(read_full && depth > 0);
let full = if read_full { full_bytes(&p, &blob) } else { None };
if full.and_then(|b| read(&p, &b)).is_none() {
// A full read cached for another caller (one allowed to read the file) must not
// stand in for the one refused or not tried here: the preview shows instead.
cache().entries.remove(&(p.key.clone(), false));
let preview = if blob.is_proxy() { Some(blob.bytes.clone()) } else { blob.proxy.clone() };
if let Some(bytes) = preview {
read_preview(&p, &bytes);
@@ -349,6 +349,30 @@ fn native_included_links_keep_missing_placed_documents_editable() {
}
}
/// Output prepared by a caller that may not read the placed file shows its preview, not the full
/// art an earlier caller that could read it left cached.
#[test]
fn a_confined_export_does_not_reuse_full_art_read_for_another_caller() {
let dir = Folder::new("placed-confined");
let other = Folder::new("placed-confined-other");
let src = dir.file("src.vectorcraft");
source(&src, 100.0, 50.0, BLUE, 0);
let mut s = session();
place(&mut s, &src);
// As a document saved with previews opens: each placed file's blob holds only its preview.
for b in std::sync::Arc::make_mut(&mut s.doc_mut().unwrap().doc).images.values_mut() {
if let Some(p) = b.proxy.clone() {
b.bytes = p;
}
}
let d = s.doc().unwrap().doc.clone();
let preview = |d: &Document| d.images.keys().any(|k| k.starts_with(vectorcraft_doc::placed_document::RESOURCE_PREFIX) && k.ends_with("/preview"));
assert!(!preview(&d.with_placed_art()), "the file is read in full");
let roots = crate::file_access::AutomationRoots::new(&[&other.0], &[]).unwrap().unwrap();
let confined = crate::file_access::confine(Some(&roots), || d.with_placed_art().into_owned());
assert!(preview(&confined), "only the preview shows");
}
#[test]
fn a_document_saved_with_previews_outputs_its_files_art() {
let dir = Folder::new("placed-preview-output");