diff --git a/crates/eps/src/import/ai/read/ops.rs b/crates/eps/src/import/ai/read/ops.rs index 5b2f86102..28e95451d 100644 --- a/crates/eps/src/import/ai/read/ops.rs +++ b/crates/eps/src/import/ai/read/ops.rs @@ -1143,8 +1143,9 @@ pub(super) struct Dictionaries<'s> { name: Option<&'s [u8]>, /// Whether the string just before the token taken is a key that ASCII85 data follows. string_key: bool, - /// The rest of the data has no `~>` or marker to stop at, so they aren't searched for again. - no_end: bool, + /// The end markers of the sections being scanned (`None`: no section) where the rest of the data + /// had no `~>` or marker to stop at, so they aren't searched for again in those sections. + no_end: Vec>, } /// Where the ASCII85 data at the start of `rest` stops: just past its `~>`, or at the comment that @@ -1176,10 +1177,11 @@ impl<'s> Dictionaries<'s> { /// Take `tok`, the token `lex` just gave, and skip the ASCII85 data that follows it, up to where /// [`data_end`] stops for `section`, so the scan still finds that section's markers. pub(super) fn pass(&mut self, tok: &super::Tok<'s>, lex: &mut super::Lexer<'s>, section: Option<(&str, &str)>) { - if self.data_follows(tok) && !self.no_end { + let end = section.map(|(_, end)| end); + if self.data_follows(tok) && !self.no_end.iter().any(|e| e.as_deref() == end) { match data_end(lex.rest(), section) { Some(stop) => lex.seek(lex.offset() + stop), - None => self.no_end = true, + None => self.no_end.push(end.map(str::to_owned)), } } } diff --git a/crates/eps/src/import/ai/tests.rs b/crates/eps/src/import/ai/tests.rs index 33e8e10f0..e6470d84d 100644 --- a/crates/eps/src/import/ai/tests.rs +++ b/crates/eps/src/import/ai/tests.rs @@ -4632,6 +4632,25 @@ fn swatch_names_are_found_past_data_in_versioned_content_that_does_not_end() { } } +/// A search for where data stops that found nothing outside a section doesn't stop a later +/// section's data at that section's end, so the named color after it still takes its name first. +/// The `/Binary` holds a group, where the reader doesn't take what follows its key as data. +#[test] +fn swatch_names_are_found_past_data_in_a_section_after_a_search_outside_sections_found_nothing() { + let sea = format!("0 1 1 0 (Sea) 0 x\n{}f\n", rect_path(0.0, 0.0, 5.0, 5.0)); + let before = "/Binary :\nu\n/ASCII85Decode ,\nU\n;\n"; + for section in [ + "%AI17_Begin_Content_if_version_gt:24 4\n%AI17_Alternate_Content\n/Binary : /ASCII85Decode ,\n%_(]<[%\n%AI17_End_Versioned_Content\n", + "%AI11_BeginTextDocument\n/AI11TextDocument : /ASCII85Decode ,\n%_(]<[%\n%AI11_EndTextDocument\n", + ] { + let art_text = format!("{before}{section}{sea}"); + let body = format!("{}{}", DOTS.replace("(Dots)", "(Sea\\n1)"), layer(&art_text)); + let d = read(stream(&body).as_bytes()).unwrap().doc; + let names: Vec<&str> = d.patterns.iter().map(|p| p.name.as_str()).collect(); + assert_eq!(names, ["Sea 2"], "{art_text}"); + } +} + /// The names the swatches take are found past the same data: a named color after it still takes /// its name first, and the pattern named after it is numbered. #[test]