History

Return to safety (#198)

Sebastian Thiel committed 5 years ago

Commit 35313b91 parent cd117043 files · +53 −28Browse files

Showing the changes to git-object/src/commit (1 of 3 files). Show all

Unified · Split

git-object/src/commit/message.rs+38−27
@@ -6,43 +6,54 @@ use crate::{ · 5 unmodified lines
66 };
77
88 mod decode {
9+ use nom::{
10+ branch::alt,
11+ bytes::complete::{tag, take_till1},
12+ combinator::all_consuming,
13+ error::ParseError,
14+ sequence::pair,
15+ IResult,
16+ };
17+
918 use crate::bstr::{BStr, ByteSlice};
10− use nom::branch::alt;
11− use nom::bytes::complete::{tag, take_till1};
12− use nom::combinator::all_consuming;
13− use nom::error::ParseError;
14− use nom::sequence::pair;
15− use nom::IResult;
16− use std::convert::TryInto;
1719
1820 fn newline<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8], E> {
1921 alt((tag(b"\r\n"), tag(b"\n")))(i)
2022 }
2123
22− pub fn nomfoo<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], (&'a BStr, Option<&'a BStr>), E> {
24+ fn subject_and_body<'a, E: ParseError<&'a [u8]>>(
25+ i: &'a [u8],
26+ ) -> IResult<&'a [u8], (&'a BStr, Option<&'a BStr>), E> {
2327 let mut c = i;
28+ let mut consumed_bytes = 0;
2429 while !c.is_empty() {
2530 c = match take_till1::<_, _, E>(|c| c == b'\n' || c == b'\r')(c) {
26− Ok((i1, segment)) => match pair::<_, _, _, E, _, _>(newline, newline)(i1) {
27− Ok((body, _)) => {
28− // SAFETY: the pointers are pointing to the same slice.
29− #[allow(unsafe_code)]
30− let consumed_bytes = unsafe { segment.as_ptr_range().end.offset_from(i.as_ptr()) };
31− return Ok((
32− &[],
33− (
34− &i[0usize..consumed_bytes.try_into().expect("positive offset")].as_bstr(),
35− (!body.is_empty()).then(|| body.as_bstr()),
36− ),
37− ));
31+ Ok((i1, segment)) => {
32+ consumed_bytes += segment.len();
33+ match pair::<_, _, _, E, _, _>(newline, newline)(i1) {
34+ Ok((body, _)) => {
35+ return Ok((
36+ &[],
37+ (
38+ &i[0usize..consumed_bytes].as_bstr(),
39+ (!body.is_empty()).then(|| body.as_bstr()),
40+ ),
41+ ));
42+ }
43+ Err(_) => match i1.get(1..) {
44+ Some(next) => {
45+ consumed_bytes += 1;
46+ next
47+ }
48+ None => break,
49+ },
3850 }
39− Err(_) => match i1.get(1..) {
40− Some(next) => next,
41− None => break,
42− },
43− },
51+ }
4452 Err(_) => match c.get(1..) {
45− Some(next) => next,
53+ Some(next) => {
54+ consumed_bytes += 1;
55+ next
56+ }
4657 None => break,
4758 },
4859 };
@@ -52,7 +63,7 @@ mod decode { · 3 unmodified lines
5263
5364 /// Returns title and body, without separator
5465 pub fn bytes(message: &[u8]) -> (&BStr, Option<&BStr>) {
55− all_consuming(nomfoo::<()>)(message).expect("cannot fail").1
66+ all_consuming(subject_and_body::<()>)(message).expect("cannot fail").1
5667 }
5768 }
5869