address review: EPS font look-back stops at the previous font; charge input characters

This commit is contained in:
Dylan M. Taylor
2026-11-03 12:58:58 +00:00
parent 62ef74067f
commit ee0f367b11
2 changed files with 14 additions and 1 deletions
+12 -1
View File
@@ -67,7 +67,8 @@ pub(super) fn embedded_fonts(ps: &[u8]) -> HashMap<String, (Rc<Vec<u8>>, bool)>
while let Some(ee) = find_from(ps, b"eexec", from) {
from = ee + 5;
let last_before = |v: &[usize]| v[..v.partition_point(|&p| p < ee)].last().copied().filter(|&p| p >= used);
let start = last_before(&heads).or_else(|| last_before(&names).map(|p| p.saturating_sub(512)));
// The fallback look-back stops at the previous font's end, so it cannot pick up its header.
let start = last_before(&heads).or_else(|| last_before(&names).map(|p| p.saturating_sub(512).max(used)));
let Some(start) = start else { continue };
let end = find_from(ps, b"cleartomark", ee).map_or(ps.len(), |p| p + 11);
if let Some(name) = name_after(&ps[start..ee], b"/FontName") {
@@ -106,4 +107,14 @@ mod tests {
assert_eq!(fonts.len(), 1);
assert!(fonts.contains_key("Real"));
}
#[test]
fn header_less_font_after_a_short_one_does_not_take_its_header() {
let a = "%!PS-AdobeFont-1.0: A\n/FontName /A def\ncurrentfile eexec\n0000\ncleartomark\n";
let b = "/FontName /B def\ncurrentfile eexec\n0000\ncleartomark\n";
let ps = format!("%!PS-Adobe-3.0 EPSF-3.0\n{a}{b}");
let fonts = embedded_fonts(ps.as_bytes());
let (data, _) = fonts.get("B").expect("second font found");
assert!(!String::from_utf8_lossy(data).contains("AdobeFont"), "{}", String::from_utf8_lossy(data));
}
}
+2
View File
@@ -95,6 +95,8 @@ impl Interp {
let ctm = self.gs.ctm;
for (i, &code) in bytes.iter().enumerate() {
let code = code as u32;
// Every input character costs at least one unit, so empty outlines are not free.
self.spend(1)?;
if let Some(g) = font.glyph(code) {
// Each outline element counts against the path limit and the budget before it
// is copied, so a long string cannot expand into unbounded geometry.