Skip to content

Commit 1b48367

Browse files
committed
first attempts to roundtrip signatures shows I parse it wrongly :D
The free space is part of the signature, not some sort of marker
1 parent f966e7f commit 1b48367

File tree

3 files changed

+16
-4
lines changed

3 files changed

+16
-4
lines changed

git-object/src/borrowed/commit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn parse(i: &[u8]) -> IResult<&[u8], Commit, Error> {
5151
let (i, encoding) =
5252
opt(|i| parse::header_field(i, b"encoding", is_not(NL)))(i).map_err(Error::context("encoding <encoding>"))?;
5353
let (i, pgp_signature) = opt(alt((
54-
|i| parse::header_field_multi_line(i, b"gpgsig").map(|(i, o)| (i, Cow::Borrowed(o.as_bstr()))),
54+
|i| parse::header_field_multi_line(i, b"gpgsig").map(|(i, o)| (i, Cow::Owned(o))),
5555
|i| parse::header_field(i, b"gpgsig", is_not(NL)).map(|(i, o)| (i, Cow::Borrowed(o.as_bstr()))),
5656
)))(i)
5757
.map_err(Error::context("gpg <signature>"))?;

git-object/src/borrowed/parse.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::{
22
borrowed::{Error, Signature},
3-
BStr, ByteSlice, Sign, Time,
3+
ByteSlice, Sign, Time,
44
};
5+
use bstr::{BStr, BString, ByteVec};
56
use btoi::btoi;
67
use nom::{
78
branch::alt,
@@ -16,7 +17,7 @@ use nom::{
1617
pub(crate) const NL: &[u8] = b"\n";
1718
pub(crate) const SPACE: &[u8] = b" ";
1819

19-
pub(crate) fn header_field_multi_line<'a>(i: &'a [u8], name: &'static [u8]) -> IResult<&'a [u8], &'a [u8], Error> {
20+
pub(crate) fn header_field_multi_line<'a>(i: &'a [u8], name: &'static [u8]) -> IResult<&'a [u8], BString, Error> {
2021
let (i, o) = peek(preceded(
2122
terminated(tag(name), tag(SPACE)),
2223
recognize(tuple((
@@ -28,7 +29,17 @@ pub(crate) fn header_field_multi_line<'a>(i: &'a [u8], name: &'static [u8]) -> I
2829
assert!(!o.is_empty());
2930
let end = &o[o.len() - 1] as *const u8 as usize;
3031
let start_input = &i[0] as *const u8 as usize;
31-
Ok((&i[end - start_input + 1..], &o[..o.len() - 1]))
32+
33+
let bytes = o[..o.len() - 1].as_bstr();
34+
let mut out = BString::from(Vec::with_capacity(bytes.len()));
35+
let mut lines = bytes.lines();
36+
out.push_str(lines.next().expect("first line"));
37+
drop(lines.next()); // empty newline marker
38+
for line in lines {
39+
out.push(b'\n');
40+
out.push_str(&line[1..]); // cut leading space
41+
}
42+
Ok((&i[end - start_input + 1..], out))
3243
}
3344

3445
pub(crate) fn header_field<'a, T>(

git-object/src/owned/ser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl Into<io::Error> for Error {
2424
pub fn header_field_multi_line(name: &[u8], value: &[u8], mut out: impl io::Write) -> io::Result<()> {
2525
let mut lines = value.as_bstr().lines();
2626
trusted_header_field(name, lines.next().expect("non-empty value"), &mut out)?;
27+
out.write_all(NL)?;
2728
for line in lines {
2829
out.write_all(SPACE)?;
2930
out.write_all(line)?;

0 commit comments

Comments
 (0)