From 007466765b591cc6f4a8b738c7c45209bbcfecad Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Fri, 13 Dec 2024 23:51:24 +0800 Subject: [PATCH 1/4] fix(common): fix ssh signature support in git messages --- common/src/utils.rs | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/common/src/utils.rs b/common/src/utils.rs index b67fe4dda..460fc4b0d 100644 --- a/common/src/utils.rs +++ b/common/src/utils.rs @@ -63,33 +63,18 @@ pub fn format_commit_msg(msg: &str, gpg_sig: Option<&str>) -> String { /// parse commit message pub fn parse_commit_msg(msg_gpg: &str) -> (String, Option) { - const GPG_SIG_START: &str = "gpgsig -----BEGIN PGP SIGNATURE-----"; - const GPG_SIG_END: &str = "-----END PGP SIGNATURE-----"; - let gpg_start = msg_gpg.find(GPG_SIG_START); - let gpg_end = msg_gpg.find(GPG_SIG_END).map(|end| end + GPG_SIG_END.len()); - let gpg_sig = match (gpg_start, gpg_end) { - (Some(start), Some(end)) => { - if start < end { - Some(msg_gpg[start..end].to_string()) - } else { - None - } - } - _ => None, - }; - match gpg_sig { - Some(gpg) => { - // Skip the leading '\n\n' (blank lines). - // Some commit messages may use '\n \n\n' or similar patterns. - // To handle such cases, remove all leading blank lines from the message. - let msg = msg_gpg[gpg_end.unwrap()..].trim_start().to_string(); - (msg, Some(gpg)) - } - None => { - assert!(msg_gpg.starts_with('\n'), "commit message format error"); - let msg = msg_gpg[1..].to_string(); // skip the leading '\n' (blank line) - (msg, None) - } + let sig_regex = Regex::new(r"(gpgsig -----BEGIN (?:PGP|SSH) SIGNATURE-----[\s\S]*?-----END (?:PGP|SSH) SIGNATURE-----)").unwrap(); + + if let Some(caps) = sig_regex.captures(msg_gpg) { + let signature = caps.get(1).map(|m| m.as_str().to_string()); + // Skip the leading '\n\n' (blank lines). + // Some commit messages may use '\n \n\n' or similar patterns. + // To handle such cases, remove all leading blank lines from the message. + let msg = sig_regex.replace(msg_gpg, "").trim_start().to_string(); + (msg, signature) + } else { + assert!(msg_gpg.starts_with('\n'), "commit message format error"); + (msg_gpg[1..].to_string(), None) } } From 05cf1c24f2b1c4a51e96d36d61954024ccc28df7 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Sat, 14 Dec 2024 00:32:34 +0800 Subject: [PATCH 2/4] you just shouldn't copy everywhere --- common/src/utils.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/common/src/utils.rs b/common/src/utils.rs index 460fc4b0d..62e68cbce 100644 --- a/common/src/utils.rs +++ b/common/src/utils.rs @@ -62,19 +62,26 @@ pub fn format_commit_msg(msg: &str, gpg_sig: Option<&str>) -> String { } /// parse commit message -pub fn parse_commit_msg(msg_gpg: &str) -> (String, Option) { - let sig_regex = Regex::new(r"(gpgsig -----BEGIN (?:PGP|SSH) SIGNATURE-----[\s\S]*?-----END (?:PGP|SSH) SIGNATURE-----)").unwrap(); - +pub fn parse_commit_msg<'a>(msg_gpg: &'a str) -> (&'a str, Option<&'a str>) { + const SIG_PATTERN: &str = r"^(gpgsig -----BEGIN (?:PGP|SSH) SIGNATURE-----[\s\S]*?-----END (?:PGP|SSH) SIGNATURE-----)"; + let sig_regex = Regex::new(SIG_PATTERN).unwrap(); if let Some(caps) = sig_regex.captures(msg_gpg) { - let signature = caps.get(1).map(|m| m.as_str().to_string()); + // Check if the signature type matches. + assert_eq!( + caps.get(2).map(|m| m.as_str()), + caps.get(3).map(|m| m.as_str()) + ); + let sig_len = caps.get(1).map(|m| m.as_str().len()).unwrap(); + let signature = &msg_gpg[..sig_len]; + // Skip the leading '\n\n' (blank lines). // Some commit messages may use '\n \n\n' or similar patterns. // To handle such cases, remove all leading blank lines from the message. - let msg = sig_regex.replace(msg_gpg, "").trim_start().to_string(); - (msg, signature) + let msg = &msg_gpg[sig_len..].trim_start(); + (msg, Some(signature)) } else { assert!(msg_gpg.starts_with('\n'), "commit message format error"); - (msg_gpg[1..].to_string(), None) + (&msg_gpg[1..], None) } } From c41d9fcdd0850c887d2705c29997ba55cd38fa41 Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Sat, 14 Dec 2024 00:35:57 +0800 Subject: [PATCH 3/4] add related test --- libra/src/command/mod.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libra/src/command/mod.rs b/libra/src/command/mod.rs index a09bb9ef8..019000913 100644 --- a/libra/src/command/mod.rs +++ b/libra/src/command/mod.rs @@ -146,15 +146,21 @@ mod test { let msg = "commit message"; let gpg_sig = "gpgsig -----BEGIN PGP SIGNATURE-----\ncontent\n-----END PGP SIGNATURE-----"; + let ssh_sig = + "gpgsig -----BEGIN SSH SIGNATURE-----\ncontent1\n-----END SSH SIGNATURE-----"; let msg_gpg = format_commit_msg(msg, Some(gpg_sig)); + let msg_ssh = format_commit_msg(msg, Some(ssh_sig)); let (msg_, gpg_sig_) = parse_commit_msg(&msg_gpg); + let (msg__, ssh_sig__) = parse_commit_msg(&msg_ssh); assert_eq!(msg, msg_); + assert_eq!(msg, msg__); assert_eq!(gpg_sig, gpg_sig_.unwrap()); + assert_eq!(ssh_sig, ssh_sig__.unwrap()); - let msg_gpg = format_commit_msg(msg, None); - let (msg_, gpg_sig_) = parse_commit_msg(&msg_gpg); + let msg_none = format_commit_msg(msg, None); + let (msg_, sig_) = parse_commit_msg(&msg_none); assert_eq!(msg, msg_); - assert_eq!(None, gpg_sig_); + assert_eq!(None, sig_); } { From 0826283c0acea4e0892196f03533ece775e8971f Mon Sep 17 00:00:00 2001 From: Iris Shi <0.0@owo.li> Date: Sat, 14 Dec 2024 09:46:49 +0800 Subject: [PATCH 4/4] make clippy happy --- common/src/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/utils.rs b/common/src/utils.rs index 62e68cbce..cc82499d3 100644 --- a/common/src/utils.rs +++ b/common/src/utils.rs @@ -62,7 +62,7 @@ pub fn format_commit_msg(msg: &str, gpg_sig: Option<&str>) -> String { } /// parse commit message -pub fn parse_commit_msg<'a>(msg_gpg: &'a str) -> (&'a str, Option<&'a str>) { +pub fn parse_commit_msg(msg_gpg: &str) -> (&str, Option<&str>) { const SIG_PATTERN: &str = r"^(gpgsig -----BEGIN (?:PGP|SSH) SIGNATURE-----[\s\S]*?-----END (?:PGP|SSH) SIGNATURE-----)"; let sig_regex = Regex::new(SIG_PATTERN).unwrap(); if let Some(caps) = sig_regex.captures(msg_gpg) {