Skip to content

Commit 994600e

Browse files
CopilotByron
andcommitted
Fix CommitRef round-tripping for malformed actors with angle brackets
- Allow angle brackets in actor names and emails for round-tripping - Keep newline restriction to preserve git format integrity - Update tests to reflect the new behavior - Resolves issue #2177 Co-authored-by: Byron <63622+Byron@users.noreply.github.com>
1 parent 442f800 commit 994600e

File tree

4 files changed

+52
-20
lines changed

4 files changed

+52
-20
lines changed

gix-actor/src/signature/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub(crate) mod write {
104104
#[derive(Debug, thiserror::Error)]
105105
#[allow(missing_docs)]
106106
pub(crate) enum Error {
107-
#[error(r"Signature name or email must not contain '<', '>' or \n")]
107+
#[error(r"Signature name or email must not contain \n")]
108108
IllegalCharacter,
109109
}
110110

@@ -144,7 +144,7 @@ pub(crate) mod write {
144144
}
145145

146146
pub(crate) fn validated_token(name: &BStr) -> Result<&BStr, Error> {
147-
if name.find_byteset(b"<>\n").is_some() {
147+
if name.find_byte(b'\n').is_some() {
148148
return Err(Error::IllegalCharacter);
149149
}
150150
Ok(name)

gix-actor/tests/identity/mod.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,43 @@ fn lenient_parsing() -> gix_testtools::Result {
4040
);
4141
let signature: Identity = identity.into();
4242
let mut output = Vec::new();
43-
let err = signature.write_to(&mut output).unwrap_err();
44-
assert_eq!(
45-
err.to_string(),
46-
r"Signature name or email must not contain '<', '>' or \n",
47-
"this isn't roundtrippable as the name is technically incorrect - must not contain brackets"
48-
);
43+
let result = signature.write_to(&mut output);
44+
45+
// Both test cases should now work since angle brackets are allowed
46+
// and the parser strips newlines from the input
47+
assert!(result.is_ok(),
48+
"angle brackets should be allowed for round-tripping, and newlines are stripped during parsing");
4949
}
5050
Ok(())
5151
}
52+
53+
#[test]
54+
fn newlines_still_rejected() -> gix_testtools::Result {
55+
// Test that newlines within the actual parsed name or email are still rejected
56+
let identity = gix_actor::IdentityRef {
57+
name: "First\nLast".into(),
58+
email: "test@example.com".into(),
59+
};
60+
let signature: Identity = identity.into();
61+
let mut output = Vec::new();
62+
let err = signature.write_to(&mut output).unwrap_err();
63+
assert_eq!(
64+
err.to_string(),
65+
r"Signature name or email must not contain \n",
66+
"newlines within parsed fields should still be rejected"
67+
);
68+
69+
let identity = gix_actor::IdentityRef {
70+
name: "First Last".into(),
71+
email: "test\n@example.com".into(),
72+
};
73+
let signature: Identity = identity.into();
74+
let mut output = Vec::new();
75+
let err = signature.write_to(&mut output).unwrap_err();
76+
assert_eq!(
77+
err.to_string(),
78+
r"Signature name or email must not contain \n",
79+
"newlines within parsed fields should still be rejected"
80+
);
81+
Ok(())
82+
}

gix-actor/tests/signature/mod.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,25 @@ mod write_to {
44
use gix_date::Time;
55

66
#[test]
7-
fn name() {
7+
fn name_with_angle_brackets() {
88
let signature = Signature {
99
name: "invalid < middlename".into(),
1010
email: "ok".into(),
1111
time: Time::default(),
1212
};
13-
assert_eq!(
14-
format!("{:?}", signature.write_to(&mut Vec::new())),
15-
"Err(Custom { kind: Other, error: IllegalCharacter })"
16-
);
13+
// This should now work - angle brackets are allowed for round-tripping
14+
assert!(signature.write_to(&mut Vec::new()).is_ok());
1715
}
1816

1917
#[test]
20-
fn email() {
18+
fn email_with_angle_brackets() {
2119
let signature = Signature {
2220
name: "ok".into(),
2321
email: "server>.example.com".into(),
2422
time: Time::default(),
2523
};
26-
assert_eq!(
27-
format!("{:?}", signature.write_to(&mut Vec::new())),
28-
"Err(Custom { kind: Other, error: IllegalCharacter })"
29-
);
24+
// This should now work - angle brackets are allowed for round-tripping
25+
assert!(signature.write_to(&mut Vec::new()).is_ok());
3026
}
3127

3228
#[test]

gix-object/tests/object/commit/from_bytes.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,14 @@ fn invalid_email_of_committer() {
3737
email: b"gh <Gregor Hartmann<gh@openoffice.org".as_bstr(),
3838
time: "1282910542 +0200",
3939
};
40+
let fixture = fixture_name("commit", "invalid-actor.txt");
41+
let commit_ref = CommitRef::from_bytes(&fixture).expect("ignore strangely formed actor format");
42+
let mut buf = vec![];
43+
let write_result = commit_ref.write_to(&mut buf);
44+
assert!(write_result.is_ok(), "write result should be OK for round-tripping");
45+
4046
assert_eq!(
41-
CommitRef::from_bytes(&fixture_name("commit", "invalid-actor.txt"))
42-
.expect("ignore strangely formed actor format"),
47+
commit_ref,
4348
CommitRef {
4449
tree: b"220738fd4199e95a2b244465168366a73ebdf271".as_bstr(),
4550
parents: [b"209fbe2d632761b30b7b17422914e11b93692833".as_bstr()].into(),

0 commit comments

Comments
 (0)