fontsan/
lib.rs

1// Copyright 2015 The Servo Project Developers.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the LICENSE file.
5//! fontsan - a sanitizer for untrusted font files.
6//!
7//! Currently, this is just a wrapper around
8//! [ots](https://github.com/khaledhosny/ots), which it builds a copy of.
9
10extern crate fontsan_woff2;
11extern crate libc;
12#[cfg(feature = "libz-rs")]
13extern crate libz_rs_sys;
14#[cfg(feature = "libz-sys")]
15extern crate libz_sys;
16
17use libc::size_t;
18use std::{convert, fmt, io};
19
20#[cfg(not(test))]
21#[link(name = "ots_glue", kind = "static")]
22extern "C" {}
23
24/// Errors that can occur when sanitising a font.
25#[derive(Debug)]
26pub enum Error {
27    /// The font data is invalid and cannot safely be sanitised.
28    ///
29    /// Some data may have been written to the output stream!
30    InvalidFont,
31
32    /// An error occurred while writing the sanitised output.
33    IoError(io::Error),
34}
35
36impl fmt::Display for Error {
37    #[inline]
38    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39        <Self as fmt::Debug>::fmt(self, f)
40    }
41}
42
43impl convert::From<io::Error> for Error {
44    #[inline]
45    fn from(e: io::Error) -> Error {
46        Error::IoError(e)
47    }
48}
49
50/// Sanitise a font file, writing the result to `output`.
51#[inline]
52pub fn process_and_write<W>(output: &mut W, font_data: &[u8]) -> Result<(), Error>
53where
54    W: io::Write + io::Seek,
55{
56    let mut stream = ffi::RustOTSStream {
57        wr: output,
58        error: None,
59    };
60    unsafe {
61        if 0 == ffi::RustOTS_Process(&mut stream, font_data.as_ptr(), font_data.len() as size_t) {
62            return Err(Error::InvalidFont);
63        }
64    }
65    match stream.error.take() {
66        Some(e) => Err(Error::IoError(e)),
67        None => Ok(()),
68    }
69}
70
71/// Convenience wrapper for `process_and_write` which writes the result to memory.
72#[inline]
73pub fn process(font_data: &[u8]) -> Result<Vec<u8>, Error> {
74    let mut out = io::Cursor::new(vec![]);
75    process_and_write(&mut out, font_data)?;
76    Ok(out.into_inner())
77}
78
79/// Implementation details.
80///
81/// This is only public so that the linker will keep it.
82#[allow(non_snake_case)]
83pub mod ffi;