From 0262ded968ece38cff5cb80626299155ef040228 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Thu, 18 Nov 2021 23:14:47 +0000 Subject: add fuzzer input generator --- bin/regen-fuzz | 6 +++++ examples/generate_fixture.rs | 60 +------------------------------------------- examples/generate_fuzz.rs | 25 ++++++++++++++++++ tests/helpers/mod.rs | 59 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 59 deletions(-) create mode 100755 bin/regen-fuzz create mode 100644 examples/generate_fuzz.rs diff --git a/bin/regen-fuzz b/bin/regen-fuzz new file mode 100755 index 0000000..cda3cf8 --- /dev/null +++ b/bin/regen-fuzz @@ -0,0 +1,6 @@ +#!/bin/sh +set -eu + +for file in tests/data/fixtures/*.in; do + cargo run --example generate_fuzz "$(basename "$file" .in)" +done diff --git a/examples/generate_fixture.rs b/examples/generate_fixture.rs index 6e36a42..b4f372d 100644 --- a/examples/generate_fixture.rs +++ b/examples/generate_fixture.rs @@ -20,7 +20,7 @@ fn main() { for line in inputs.lines() { let line = line.unwrap(); - let input = unhex(line.as_bytes()); + let input = helpers::unhex(line.as_bytes()); let mut input_file = std::fs::File::create(format!( "tests/data/fixtures/{}/{}.typescript", name, i @@ -43,61 +43,3 @@ fn main() { i += 1; } } - -fn unhex(s: &[u8]) -> Vec { - let mut ret = vec![]; - let mut i = 0; - while i < s.len() { - if s[i] == b'\\' { - match s[i + 1] { - b'\\' => { - ret.push(b'\\'); - i += 2; - } - b'x' => { - let upper = s[i + 2]; - let lower = s[i + 3]; - ret.push(helpers::hex(upper, lower).unwrap()); - i += 4; - } - b'u' => { - assert_eq!(s[i + 2], b'{'); - let mut digits = vec![]; - let mut j = i + 3; - while s[j] != b'}' { - digits.push(s[j]); - j += 1; - } - let digits: Vec<_> = digits - .iter() - .copied() - .skip_while(|x| x == &b'0') - .collect(); - let digits = String::from_utf8(digits).unwrap(); - let codepoint = u32::from_str_radix(&digits, 16).unwrap(); - let c = char::try_from(codepoint).unwrap(); - let mut bytes = [0; 4]; - ret.extend(c.encode_utf8(&mut bytes).bytes()); - i = j + 1; - } - b'r' => { - ret.push(0x0d); - i += 2; - } - b'n' => { - ret.push(0x0a); - i += 2; - } - b't' => { - ret.push(0x09); - i += 2; - } - _ => panic!("invalid escape"), - } - } else { - ret.push(s[i]); - i += 1; - } - } - ret -} diff --git a/examples/generate_fuzz.rs b/examples/generate_fuzz.rs new file mode 100644 index 0000000..92c983b --- /dev/null +++ b/examples/generate_fuzz.rs @@ -0,0 +1,25 @@ +use std::io::BufRead as _; +use std::io::Write as _; + +#[path = "../tests/helpers/mod.rs"] +mod helpers; + +fn main() { + let name = std::env::args().nth(1).unwrap(); + let _ = std::fs::remove_file(format!("fuzz/in/{}", name)); + + let inputs = + std::fs::File::open(format!("tests/data/fixtures/{}.in", name)) + .unwrap(); + let inputs = std::io::BufReader::new(inputs); + + let mut bytes = vec![]; + for line in inputs.lines() { + let line = line.unwrap(); + let input = helpers::unhex(line.as_bytes()); + bytes.extend(input.iter()); + } + let mut input_file = + std::fs::File::create(format!("fuzz/in/{}", name)).unwrap(); + input_file.write_all(&bytes).unwrap(); +} diff --git a/tests/helpers/mod.rs b/tests/helpers/mod.rs index 20de2d4..d3dd05d 100644 --- a/tests/helpers/mod.rs +++ b/tests/helpers/mod.rs @@ -289,3 +289,62 @@ fn hex_char(c: u8) -> Result { pub fn hex(upper: u8, lower: u8) -> Result { Ok(hex_char(upper)? * 16 + hex_char(lower)?) } + +#[allow(dead_code)] +pub fn unhex(s: &[u8]) -> Vec { + let mut ret = vec![]; + let mut i = 0; + while i < s.len() { + if s[i] == b'\\' { + match s[i + 1] { + b'\\' => { + ret.push(b'\\'); + i += 2; + } + b'x' => { + let upper = s[i + 2]; + let lower = s[i + 3]; + ret.push(hex(upper, lower).unwrap()); + i += 4; + } + b'u' => { + assert_eq!(s[i + 2], b'{'); + let mut digits = vec![]; + let mut j = i + 3; + while s[j] != b'}' { + digits.push(s[j]); + j += 1; + } + let digits: Vec<_> = digits + .iter() + .copied() + .skip_while(|x| x == &b'0') + .collect(); + let digits = String::from_utf8(digits).unwrap(); + let codepoint = u32::from_str_radix(&digits, 16).unwrap(); + let c = char::try_from(codepoint).unwrap(); + let mut bytes = [0; 4]; + ret.extend(c.encode_utf8(&mut bytes).bytes()); + i = j + 1; + } + b'r' => { + ret.push(0x0d); + i += 2; + } + b'n' => { + ret.push(0x0a); + i += 2; + } + b't' => { + ret.push(0x09); + i += 2; + } + _ => panic!("invalid escape"), + } + } else { + ret.push(s[i]); + i += 1; + } + } + ret +} -- cgit v1.2.3-54-g00ecf