Skip to content

Commit 7753ce7

Browse files
committed
build_helper: handle emails containing square brackets
The `git` API shells out to `git rev-list` and was directly passing an email string to the command's `--author` flag. That flag interprets its arguments as a regular expression, meaning that characters like square brackets (`[]`) in the email string made the command fail to find a commit matching the author e-mail This commit escapes the email string prior to passing it to `git rev-list`. The change is tested in the `bootstrap` crate because it contains the testing infrastructure to create temporary git repositories. fixes #140669
1 parent 1b9efcd commit 7753ce7

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

src/bootstrap/src/core/builder/tests.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::env::VarError;
22
use std::{panic, thread};
33

4+
use build_helper::ci::CiEnv;
5+
use build_helper::git::GitConfig;
46
use build_helper::stage0_parser::parse_stage0_file;
57
use llvm::prebuilt_llvm_config;
68

@@ -267,6 +269,32 @@ fn ci_rustc_if_unchanged_invalidate_on_library_changes_in_ci() {
267269
});
268270
}
269271

272+
// this test is similar to the other two `ci_rustc_if_unchanged_` tests below but overrides
273+
// `merge_bot_email`. it uses the lower level `build_helper::git` API because
274+
// `parse_config_download_rustc_at` is hard-coded to use the `git_merge_commit_email` value in
275+
// the git-tracked file `/src/stage0`
276+
#[test]
277+
fn ci_rustc_with_square_bracket_in_author_email() {
278+
git_test(|ctx| {
279+
let author_email = "bors[bot]@example.com";
280+
ctx.merge_bot_email = format!("Merge bot <{}>", author_email);
281+
ctx.write("src/ci/channel", "nightly");
282+
ctx.commit();
283+
284+
let sha = ctx.create_upstream_merge(&["compiler/bar"]);
285+
286+
let git_config =
287+
GitConfig { nightly_branch: &ctx.nightly_branch, git_merge_commit_email: author_email };
288+
let got = build_helper::git::get_closest_upstream_commit(
289+
Some(ctx.get_path()),
290+
&git_config,
291+
CiEnv::None,
292+
);
293+
294+
assert_eq!(got, Ok(Some(sha)));
295+
});
296+
}
297+
270298
#[test]
271299
fn ci_rustc_if_unchanged_do_not_invalidate_on_library_changes_outside_ci() {
272300
git_test(|ctx| {

src/build_helper/src/git.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ pub struct GitConfig<'a> {
99
pub git_merge_commit_email: &'a str,
1010
}
1111

12+
impl GitConfig<'_> {
13+
// prepares `git_merge_commit_email` before it gets passed to `git rev-list`'s `--author` flag
14+
//
15+
// the `--author` flag takes a "pattern" (regular expression) not a substring so any
16+
// square bracket in the original email needs to be escaped
17+
fn author_email(&self) -> String {
18+
self.git_merge_commit_email.replace('[', "\\[").replace(']', "\\]")
19+
}
20+
}
21+
1222
/// Runs a command and returns the output
1323
pub fn output_result(cmd: &mut Command) -> Result<String, String> {
1424
let output = match cmd.stderr(Stdio::inherit()).output() {
@@ -183,7 +193,7 @@ fn get_latest_upstream_commit_that_modified_files(
183193
"-n1",
184194
&upstream,
185195
"--author",
186-
git_config.git_merge_commit_email,
196+
&git_config.author_email(),
187197
]);
188198

189199
if !target_paths.is_empty() {
@@ -198,7 +208,7 @@ fn get_latest_upstream_commit_that_modified_files(
198208
/// author.
199209
///
200210
/// If we are in CI, we simply return our first parent.
201-
fn get_closest_upstream_commit(
211+
pub fn get_closest_upstream_commit(
202212
git_dir: Option<&Path>,
203213
config: &GitConfig<'_>,
204214
env: CiEnv,
@@ -227,13 +237,7 @@ fn get_closest_upstream_commit(
227237
// chronologically recent bors commit.
228238
// Here we assume that none of our subtrees use bors anymore, and that all their old bors
229239
// commits are way older than recent rustc bors commits!
230-
git.args([
231-
"rev-list",
232-
"--author-date-order",
233-
&format!("--author={}", config.git_merge_commit_email),
234-
"-n1",
235-
&base,
236-
]);
240+
git.args(["rev-list", "--author-date-order", "--author", &config.author_email(), "-n1", &base]);
237241

238242
let output = output_result(&mut git)?.trim().to_owned();
239243
if output.is_empty() { Ok(None) } else { Ok(Some(output)) }

0 commit comments

Comments
 (0)