diff --git a/crates/doc/src/placed_document.rs b/crates/doc/src/placed_document.rs index 310d7b784..33eccb178 100644 --- a/crates/doc/src/placed_document.rs +++ b/crates/doc/src/placed_document.rs @@ -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); diff --git a/crates/engine/src/tests/placed_document.rs b/crates/engine/src/tests/placed_document.rs index 0ea8fd33b..08071df05 100644 --- a/crates/engine/src/tests/placed_document.rs +++ b/crates/engine/src/tests/placed_document.rs @@ -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");