Files

177 lines
4.6 KiB
Rust

#[rustfmt::skip] mod aat;
#[rustfmt::skip] mod ankr;
#[rustfmt::skip] mod cff1;
#[rustfmt::skip] mod cmap;
#[rustfmt::skip] mod colr;
#[rustfmt::skip] mod feat;
#[rustfmt::skip] mod glyf;
#[rustfmt::skip] mod hmtx;
#[rustfmt::skip] mod maxp;
#[rustfmt::skip] mod sbix;
#[rustfmt::skip] mod trak;
use ttf_parser::{fonts_in_collection, Face, FaceParsingError};
#[allow(dead_code)]
#[derive(Clone, Copy)]
pub enum Unit {
Raw(&'static [u8]),
Int8(i8),
UInt8(u8),
Int16(i16),
UInt16(u16),
Int32(i32),
UInt32(u32),
Fixed(f32),
}
pub fn convert(units: &[Unit]) -> Vec<u8> {
let mut data = Vec::with_capacity(256);
for v in units {
convert_unit(*v, &mut data);
}
data
}
fn convert_unit(unit: Unit, data: &mut Vec<u8>) {
match unit {
Unit::Raw(bytes) => {
data.extend_from_slice(bytes);
}
Unit::Int8(n) => {
data.extend_from_slice(&i8::to_be_bytes(n));
}
Unit::UInt8(n) => {
data.extend_from_slice(&u8::to_be_bytes(n));
}
Unit::Int16(n) => {
data.extend_from_slice(&i16::to_be_bytes(n));
}
Unit::UInt16(n) => {
data.extend_from_slice(&u16::to_be_bytes(n));
}
Unit::Int32(n) => {
data.extend_from_slice(&i32::to_be_bytes(n));
}
Unit::UInt32(n) => {
data.extend_from_slice(&u32::to_be_bytes(n));
}
Unit::Fixed(n) => {
data.extend_from_slice(&i32::to_be_bytes((n * 65536.0) as i32));
}
}
}
#[test]
fn empty_font() {
assert_eq!(
Face::parse(&[], 0).unwrap_err(),
FaceParsingError::UnknownMagic
);
}
#[test]
fn zero_tables() {
use Unit::*;
let data = convert(&[
Raw(&[0x00, 0x01, 0x00, 0x00]), // magic
UInt16(0), // numTables
UInt16(0), // searchRange
UInt16(0), // entrySelector
UInt16(0), // rangeShift
]);
assert_eq!(
Face::parse(&data, 0).unwrap_err(),
FaceParsingError::NoHeadTable
);
}
#[test]
fn tables_count_overflow() {
use Unit::*;
let data = convert(&[
Raw(&[0x00, 0x01, 0x00, 0x00]), // magic
UInt16(std::u16::MAX), // numTables
UInt16(0), // searchRange
UInt16(0), // entrySelector
UInt16(0), // rangeShift
]);
assert_eq!(
Face::parse(&data, 0).unwrap_err(),
FaceParsingError::MalformedFont
);
}
#[test]
fn empty_font_collection() {
use Unit::*;
let data = convert(&[
Raw(&[0x74, 0x74, 0x63, 0x66]), // magic
UInt16(0), // majorVersion
UInt16(0), // minorVersion
UInt32(0), // numFonts
]);
assert_eq!(fonts_in_collection(&data), Some(0));
assert_eq!(
Face::parse(&data, 0).unwrap_err(),
FaceParsingError::FaceIndexOutOfBounds
);
}
#[test]
fn font_collection_num_fonts_overflow() {
use Unit::*;
let data = convert(&[
Raw(&[0x74, 0x74, 0x63, 0x66]), // magic
UInt16(0), // majorVersion
UInt16(0), // minorVersion
UInt32(std::u32::MAX), // numFonts
]);
assert_eq!(fonts_in_collection(&data), Some(std::u32::MAX));
assert_eq!(
Face::parse(&data, 0).unwrap_err(),
FaceParsingError::MalformedFont
);
}
#[test]
fn font_index_overflow() {
use Unit::*;
let data = convert(&[
Raw(&[0x74, 0x74, 0x63, 0x66]), // magic
UInt16(0), // majorVersion
UInt16(0), // minorVersion
UInt32(1), // numFonts
UInt32(12), // offset [0]
]);
assert_eq!(fonts_in_collection(&data), Some(1));
assert_eq!(
Face::parse(&data, std::u32::MAX).unwrap_err(),
FaceParsingError::FaceIndexOutOfBounds
);
}
#[test]
fn font_index_overflow_on_regular_font() {
use Unit::*;
let data = convert(&[
Raw(&[0x00, 0x01, 0x00, 0x00]), // magic
UInt16(0), // numTables
UInt16(0), // searchRange
UInt16(0), // entrySelector
UInt16(0), // rangeShift
]);
assert_eq!(fonts_in_collection(&data), None);
assert_eq!(
Face::parse(&data, 1).unwrap_err(),
FaceParsingError::FaceIndexOutOfBounds
);
}