swf: Fix incorrect parsing of DefineFont2/3 with device fonts

This commit is contained in:
Mike Welsh 2019-10-10 15:47:37 -07:00
parent 614903bdec
commit 657a0baec0
2 changed files with 72 additions and 52 deletions

View File

@ -1143,6 +1143,9 @@ impl<R: Read> Reader<R> {
.by_ref() .by_ref()
.take(name_len.into()) .take(name_len.into())
.read_to_string(&mut name)?; .read_to_string(&mut name)?;
// TODO: SWF19 states that the font name should not have a terminating null byte,
// but it often does (depends on Flash IDE version?)
// We should probably strip anything past the first null.
let num_glyphs = self.read_u16()? as usize; let num_glyphs = self.read_u16()? as usize;
let mut glyphs = Vec::with_capacity(num_glyphs); let mut glyphs = Vec::with_capacity(num_glyphs);
@ -1156,6 +1159,18 @@ impl<R: Read> Reader<R> {
}, },
); );
// SWF19 p. 164 doesn't make it super clear: If there are no glyphs,
// then the following tables are omitted. But the table offset values
// may or may not be written... (depending on Flash IDE version that was used?)
if num_glyphs == 0 {
// Try to read the CodeTableOffset. It may or may not be present,
// so just dump any error.
if has_wide_offsets {
let _ = self.read_u32();
} else {
let _ = self.read_u16();
}
} else {
// OffsetTable // OffsetTable
// We are throwing these away. // We are throwing these away.
for _ in &mut glyphs { for _ in &mut glyphs {
@ -1191,7 +1206,9 @@ impl<R: Read> Reader<R> {
u16::from(self.read_u8()?) u16::from(self.read_u8()?)
}; };
} }
}
// TODO: Is it possible to have a layout when there are no glyphs?
let layout = if has_layout { let layout = if has_layout {
let ascent = self.read_u16()?; let ascent = self.read_u16()?;
let descent = self.read_u16()?; let descent = self.read_u16()?;

View File

@ -2391,6 +2391,8 @@ impl<W: Write> Writer<W> {
writer.output.write_all(font.name.as_bytes())?; writer.output.write_all(font.name.as_bytes())?;
writer.write_u16(num_glyphs as u16)?; writer.write_u16(num_glyphs as u16)?;
// If there are no glyphs, then the following tables are omitted.
if num_glyphs > 0 {
// OffsetTable // OffsetTable
for offset in offsets { for offset in offsets {
if has_wide_offsets { if has_wide_offsets {
@ -2419,6 +2421,7 @@ impl<W: Write> Writer<W> {
writer.write_u8(glyph.code as u8)?; writer.write_u8(glyph.code as u8)?;
} }
} }
}
if let Some(ref layout) = font.layout { if let Some(ref layout) = font.layout {
writer.write_u16(layout.ascent)?; writer.write_u16(layout.ascent)?;