diff options
| author | Nathaniel Brough <nathaniel.brough@gmail.com> | 2023-12-05 10:26:58 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-05 19:26:58 +0100 |
| commit | 9aadb18186c0804f6cc6179bf8ea993337dc669d (patch) | |
| tree | 95cc87193e1b9d1255b45894830ba98b372bde5f /tests | |
| parent | 0ebce56b36ea2a875609949f4da81c9ca6a4a081 (diff) | |
Add simple fuzz testing (#2581)
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/fuzz/Cargo.toml | 27 | ||||
| -rw-r--r-- | tests/fuzz/src/compile.rs | 74 | ||||
| -rw-r--r-- | tests/fuzz/src/parse.rs | 8 |
3 files changed, 109 insertions, 0 deletions
diff --git a/tests/fuzz/Cargo.toml b/tests/fuzz/Cargo.toml new file mode 100644 index 00000000..1b9e6b26 --- /dev/null +++ b/tests/fuzz/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "typst-fuzz" +version.workspace = true +edition.workspace = true +publish = false + +[package.metadata] +cargo-fuzz = true + +[dependencies] +typst = { workspace = true } +typst-render = { workspace = true } +typst-syntax = { workspace = true } +comemo = { workspace = true } +libfuzzer-sys = { workspace = true } + +[[bin]] +name = "parse" +path = "src/parse.rs" +test = false +doc = false + +[[bin]] +name = "compile" +path = "src/compile.rs" +test = false +doc = false diff --git a/tests/fuzz/src/compile.rs b/tests/fuzz/src/compile.rs new file mode 100644 index 00000000..deb71778 --- /dev/null +++ b/tests/fuzz/src/compile.rs @@ -0,0 +1,74 @@ +#![no_main] + +use comemo::Prehashed; +use libfuzzer_sys::fuzz_target; +use typst::diag::{FileError, FileResult}; +use typst::eval::Tracer; +use typst::foundations::{Bytes, Datetime}; +use typst::syntax::{FileId, Source}; +use typst::text::{Font, FontBook}; +use typst::visualize::Color; +use typst::{Library, World}; + +const FONT: &[u8] = include_bytes!("../../../assets/fonts/LinLibertine_R.ttf"); + +struct FuzzWorld { + library: Prehashed<Library>, + book: Prehashed<FontBook>, + font: Font, + source: Source, +} + +impl FuzzWorld { + fn new(text: &str) -> Self { + let font = Font::new(FONT.into(), 0).unwrap(); + let book = FontBook::from_fonts([&font]); + Self { + library: Prehashed::new(Library::build()), + book: Prehashed::new(book), + font, + source: Source::detached(text), + } + } +} + +impl World for FuzzWorld { + fn library(&self) -> &Prehashed<Library> { + &self.library + } + + fn book(&self) -> &Prehashed<FontBook> { + &self.book + } + + fn main(&self) -> Source { + self.source.clone() + } + + fn source(&self, src: FileId) -> FileResult<Source> { + Err(FileError::NotFound(src.vpath().as_rootless_path().into())) + } + + fn file(&self, src: FileId) -> FileResult<Bytes> { + Err(FileError::NotFound(src.vpath().as_rootless_path().into())) + } + + fn font(&self, _: usize) -> Option<Font> { + Some(self.font.clone()) + } + + fn today(&self, _: Option<i64>) -> Option<Datetime> { + None + } +} + +fuzz_target!(|text: &str| { + let world = FuzzWorld::new(text); + let mut tracer = Tracer::new(); + if let Ok(document) = typst::compile(&world, &mut tracer) { + if let Some(page) = document.pages.first() { + std::hint::black_box(typst_render::render(page, 1.0, Color::WHITE)); + } + } + comemo::evict(10); +}); diff --git a/tests/fuzz/src/parse.rs b/tests/fuzz/src/parse.rs new file mode 100644 index 00000000..f151661a --- /dev/null +++ b/tests/fuzz/src/parse.rs @@ -0,0 +1,8 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; +use typst_syntax::parse; + +fuzz_target!(|text: &str| { + std::hint::black_box(parse(text)); +}); |
