libafl/inputs/
nautilus.rs1use alloc::{rc::Rc, vec::Vec};
3use core::{
4 cell::RefCell,
5 hash::{Hash, Hasher},
6};
7
8use libafl_bolts::{HasLen, ownedref::OwnedSlice};
9use serde::{Deserialize, Serialize};
10
11use super::BytesInput;
12use crate::{
13 common::nautilus::grammartec::{
14 newtypes::NodeId,
15 rule::RuleIdOrCustom,
16 tree::{Tree, TreeLike},
17 },
18 generators::nautilus::NautilusContext,
19 inputs::{Input, InputConverter, InputToBytes},
20};
21
22#[derive(Serialize, Deserialize, Clone, Debug)]
24pub struct NautilusInput {
25 pub tree: Tree,
27}
28
29impl Input for NautilusInput {}
30
31impl From<NautilusInput> for Rc<RefCell<NautilusInput>> {
33 fn from(input: NautilusInput) -> Self {
34 Rc::new(RefCell::new(input))
35 }
36}
37
38impl HasLen for NautilusInput {
39 #[inline]
40 fn len(&self) -> usize {
41 self.tree.size()
42 }
43}
44
45impl NautilusInput {
46 #[must_use]
48 pub fn new(tree: Tree) -> Self {
49 Self { tree }
50 }
51
52 #[must_use]
54 pub fn empty() -> Self {
55 Self {
56 tree: Tree {
57 rules: vec![],
58 sizes: vec![],
59 paren: vec![],
60 },
61 }
62 }
63
64 pub fn unparse(&self, context: &NautilusContext, bytes: &mut Vec<u8>) {
66 bytes.clear();
67 self.tree.unparse(NodeId::from(0), &context.ctx, bytes);
68 }
69
70 #[must_use]
72 pub fn tree(&self) -> &Tree {
73 &self.tree
74 }
75
76 #[must_use]
78 pub fn tree_mut(&mut self) -> &mut Tree {
79 &mut self.tree
80 }
81}
82
83impl Hash for NautilusInput {
84 fn hash<H: Hasher>(&self, state: &mut H) {
85 self.tree().paren.hash(state);
86 for r in &self.tree().rules {
87 match r {
88 RuleIdOrCustom::Custom(a, b) => {
89 a.hash(state);
90 b.hash(state);
91 }
92 RuleIdOrCustom::Rule(a) => a.hash(state),
93 }
94 }
95 self.tree().sizes.hash(state);
96 }
97}
98
99#[derive(Debug)]
101pub struct NautilusBytesConverter<'a> {
102 ctx: &'a NautilusContext,
103}
104
105impl<'a> NautilusBytesConverter<'a> {
106 #[must_use]
107 pub fn new(ctx: &'a NautilusContext) -> Self {
109 Self { ctx }
110 }
111}
112
113impl InputConverter for NautilusBytesConverter<'_> {
114 type From = NautilusInput;
115 type To = BytesInput;
116
117 fn convert(&mut self, input: Self::From) -> Result<Self::To, libafl_bolts::Error> {
118 let mut bytes = vec![];
119 input.unparse(self.ctx, &mut bytes);
120 Ok(BytesInput::new(bytes))
121 }
122}
123
124impl InputToBytes<NautilusInput> for NautilusBytesConverter<'_> {
125 fn to_bytes<'a>(&mut self, input: &'a NautilusInput) -> OwnedSlice<'a, u8> {
126 let mut bytes = vec![];
127 input.unparse(self.ctx, &mut bytes);
128 OwnedSlice::from(bytes)
129 }
130}