nss_certdata_parser/
reader.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use super::Error;
6use syntax::{Token, Value, Attr, attribute, begindata};
7use structured::Object;
8
9use nom::{slice_to_offsets, Err, ErrorKind, IResult};
10use std::collections::HashMap;
11use std::convert::From;
12use std::io;
13use std::io::BufRead;
14use std::mem;
15
16pub type Offset = u64;
17
18#[derive(Debug)]
19pub struct ParseError {
20    // TODO: more information would be good.  Like the line number.
21    // (Or at least one or more ErrorKinds.)
22    pub byte_offset: Offset,
23    pub buf_left: usize,
24    pub what: ErrorKind,
25}
26
27fn nom_error_info<'a, E: Clone>(err: &'a Err<&'a [u8], E>) -> (&'a [u8], ErrorKind<E>) {
28    match *err {
29        Err::Code(_) => unimplemented!(),
30        Err::Node(_, ref err_box) => nom_error_info(err_box),
31        Err::Position(ref ek, loc) => (loc, ek.clone()),
32        Err::NodePosition(_, _, ref err_box) => nom_error_info(err_box),
33    }
34}
35
36// The code duplication makes me sad, and this ought to be properly tested....
37fn bufferize<I, O, E, F>(mut src: I, mut f: F) -> Result<Option<(usize, O)>, E>
38    where I: BufRead,
39          E: From<io::Error>,
40          F: for<'a> FnMut(&'a [u8]) -> Result<Option<(usize, O)>, E>
41{
42    let mut big_buf = Vec::new();
43    // Non-lexical lifetimes would make this code cleaner.
44    match {
45        let buf = try!(src.fill_buf());
46        if buf.is_empty() {
47            return Ok(None);
48        }
49        match try!(f(buf)) {
50            None => { big_buf.extend_from_slice(buf); None },
51            some @ Some(_) => some
52        }
53    } {
54        Some((used, res)) => {
55            src.consume(used);
56            return Ok(Some((used, res)));
57        },
58        None => {
59            src.consume(big_buf.len());
60        }
61    };
62    loop {
63        let old_len = big_buf.len();
64        big_buf.extend_from_slice({
65            let buf = try!(src.fill_buf());
66            if buf.is_empty() {
67                return Ok(None);
68            } 
69            buf
70        });
71        match try!(f(&big_buf)) {
72            Some((used, res)) => {
73                src.consume(used - old_len);
74                return Ok(Some((used, res)));
75            },
76            None => src.consume(big_buf.len() - old_len),
77        }
78    }
79}
80
81// Applies a `nom` parser to a `BufRead`, trying to parse from the
82// input's own buffer if possible, or else allocating a larger
83// temporary buffer if needed.
84//
85// FIXME: this is fundamentally broken; nom expects the entire input,
86// and in some cases an unexpected "end of file" (which in this usage
87// is really just the end of an arbitrary buffer) can cause Error
88// results rather than Incomplete.  Worse, the reported location for
89// that error might *not* be the end of the buffer, depending on how
90// the grammar.  This should be replaced by either reading the entire
91// file into memory or using a handwritten parser.
92fn apply_nom<I, O, P>(mut parser: P, off: Offset, src: I)
93                   -> Result<Option<(Offset, O)>, Error>
94    where I: BufRead,
95          P: for<'a> FnMut(&'a [u8]) -> IResult<&'a [u8], O>
96{
97    if let Some((used, res)) = try!(bufferize(src, |buf| {
98        match parser(buf) {
99            IResult::Done(rest, res) => {
100                let (used, _) = slice_to_offsets(buf, rest);
101                Ok(Some((used, res)))
102            }
103            IResult::Error(err) => {
104                let (rest, what) = nom_error_info(&err);
105                // This is a hack to try to recognize spurious errors.
106                // Might cause false negatives.
107                if !rest.contains(&b'\n') {
108                    Ok(None)
109                } else {
110                    let (seen, _) = slice_to_offsets(buf, rest);
111                    Err(Error::ParseError(ParseError{
112                        byte_offset: off + (seen as Offset),
113                        buf_left: rest.len(),
114                        what: what,
115                    }.into()))
116                }
117            }
118            IResult::Incomplete(_) => {
119                Ok(None)
120            }
121        }
122    })) {
123        Ok(Some((off + (used as Offset), res)))
124    } else {
125        Ok(None)
126    }
127}
128
129pub struct AttrIter<I: BufRead> {
130    src: I,
131    offset: Offset,
132    had_error: bool,
133}
134
135impl<I: BufRead> AttrIter<I> {
136    pub fn new(src: I) -> Self {
137        AttrIter {
138            src: src,
139            offset: 0,
140            had_error: false
141        }
142    }
143}
144impl<I: BufRead> Iterator for AttrIter<I> {
145    type Item = Result<Attr, Error>;
146    fn next(&mut self) -> Option<Self::Item> {
147        if self.had_error {
148            return None;
149        }
150        if self.offset == 0 {
151            match apply_nom(begindata, self.offset, &mut self.src) {
152                Err(err) => {
153                    self.had_error = true;
154                    return Some(Err(err));
155                }
156                Ok(None) => {
157                    return None;
158                }
159                Ok(Some((offset, ()))) => {
160                    assert!(offset != 0);
161                    self.offset = offset;
162                }
163            }
164        }
165        match apply_nom(attribute, self.offset, &mut self.src) {
166            Err(err) => {
167                self.had_error = true;
168                Some(Err(err))
169            }
170            Ok(None) => None,
171            Ok(Some((offset, attr))) => {
172                assert!(offset > self.offset);
173                self.offset = offset;
174                Some(Ok(attr))
175            }
176        }
177    }
178}
179
180pub type RawObject = HashMap<Token, Value>;
181
182pub struct RawObjectIter<I: BufRead> {
183    inner: AttrIter<I>,
184    acc: RawObject,
185    done: bool,
186}
187
188impl<I: BufRead> RawObjectIter<I> {
189    pub fn new(src: I) -> Self {
190        RawObjectIter {
191            inner: AttrIter::new(src),
192            acc: HashMap::new(),
193            done: false,
194        }
195    }
196}
197
198impl<I: BufRead> Iterator for RawObjectIter<I> {
199    type Item = Result<RawObject, Error>;
200    fn next(&mut self) -> Option<Self::Item> {
201        if self.done {
202            return None;
203        }
204        loop {
205            assert!(!self.done);
206            match self.inner.next() {
207                Some(Err(err)) => {
208                    self.done = true;
209                    return Some(Err(err))
210                }
211                Some(Ok((key, value))) => {
212                    if key == "CKA_CLASS" && !self.acc.is_empty() {
213                        let mut next_obj = HashMap::new();
214                        next_obj.insert(key, value);
215                        return Some(Ok(mem::replace(&mut self.acc, next_obj)))
216                    } else {
217                        self.acc.insert(key, value);
218                    }
219                },
220                None => {
221                    self.done = true;
222                    if !self.acc.is_empty() {
223                        return Some(Ok(mem::replace(&mut self.acc, HashMap::new())));
224                    } else {
225                        return None;
226                    }
227                }
228            }
229        }
230    }
231}
232
233// Does this really belong in this module (vs. structured)?  Does it matter?
234pub struct ObjectIter<I: BufRead> {
235    inner: RawObjectIter<I>,
236}
237
238impl<I: BufRead> From<ObjectIter<I>> for RawObjectIter<I> {
239    fn from(outer: ObjectIter<I>) -> Self {
240        outer.inner
241    }
242}
243impl<I: BufRead> From<RawObjectIter<I>> for ObjectIter<I> {
244    fn from(inner: RawObjectIter<I>) -> Self {
245        ObjectIter { inner: inner }
246    }
247}
248
249impl<I: BufRead> ObjectIter<I> {
250    pub fn new(src: I) -> Self {
251        RawObjectIter::new(src).into()
252    }
253    pub fn into_inner(self) -> RawObjectIter<I> {
254        self.into()
255    }
256}
257
258impl<I: BufRead> Iterator for ObjectIter<I> {
259    type Item = Result<Object, Error>;
260    fn next(&mut self) -> Option<Self::Item> {
261        loop {
262            match self.inner.next() {
263                None => return None,
264                Some(Err(err)) => return Some(Err(err)),
265                Some(Ok(obj)) => match Object::from_raw(obj) {
266                    Err(err) => return Some(Err(err.into())),
267                    Ok(Some(obj)) => return Some(Ok(obj)),
268                    Ok(None) => ()
269                }
270            };
271        }
272    }
273}