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
6};6};
7 7
8mod decode {8mod 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
9 use crate::bstr::{BStr, ByteSlice};18 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;
17 19
18 fn newline<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8], E> {20 fn newline<'a, E: ParseError<&'a [u8]>>(i: &'a [u8]) -> IResult<&'a [u8], &'a [u8], E> {
19 alt((tag(b"\r\n"), tag(b"\n")))(i)21 alt((tag(b"\r\n"), tag(b"\n")))(i)
20 }22 }
21 23
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> {
23 let mut c = i;27 let mut c = i;
28 let mut consumed_bytes = 0;
24 while !c.is_empty() {29 while !c.is_empty() {
25 c = match take_till1::<_, _, E>(|c| c == b'\n' || c == b'\r')(c) {30 c = match take_till1::<_, _, E>(|c| c == b'\n' || c == b'\r')(c) {
26 Ok((i1, segment)) => match pair::<_, _, _, E, _, _>(newline, newline)(i1) {31 Ok((i1, segment)) => {
27 Ok((body, _)) => {32 consumed_bytes += segment.len();
28 // SAFETY: the pointers are pointing to the same slice.33 match pair::<_, _, _, E, _, _>(newline, newline)(i1) {
29 #[allow(unsafe_code)]34 Ok((body, _)) => {
30 let consumed_bytes = unsafe { segment.as_ptr_range().end.offset_from(i.as_ptr()) };35 return Ok((
31 return Ok((36 &[],
32 &[],37 (
33 (38 &i[0usize..consumed_bytes].as_bstr(),
34 &i[0usize..consumed_bytes.try_into().expect("positive offset")].as_bstr(),39 (!body.is_empty()).then(|| body.as_bstr()),
35 (!body.is_empty()).then(|| body.as_bstr()),40 ),
36 ),41 ));
37 ));42 }
43 Err(_) => match i1.get(1..) {
44 Some(next) => {
45 consumed_bytes += 1;
46 next
47 }
48 None => break,
49 },
38 }50 }
39 Err(_) => match i1.get(1..) {51 }
40 Some(next) => next,
41 None => break,
42 },
43 },
44 Err(_) => match c.get(1..) {52 Err(_) => match c.get(1..) {
45 Some(next) => next,53 Some(next) => {
54 consumed_bytes += 1;
55 next
56 }
46 None => break,57 None => break,
47 },58 },
48 };59 };
@@ -52,7 +63,7 @@ mod decode { · 3 unmodified lines
52 63
53 /// Returns title and body, without separator64 /// Returns title and body, without separator
54 pub fn bytes(message: &[u8]) -> (&BStr, Option<&BStr>) {65 pub fn bytes(message: &[u8]) -> (&BStr, Option<&BStr>) {
55 all_consuming(nomfoo::<()>)(message).expect("cannot fail").166 all_consuming(subject_and_body::<()>)(message).expect("cannot fail").1
56 }67 }
57}68}
58 69