From db9171967b320946ecdb5685121a37eb0862c905 Mon Sep 17 00:00:00 2001 From: Frank Yang Date: Wed, 9 Nov 2022 00:26:39 +0800 Subject: [PATCH] fix: return non UTF-8 error message Signed-off-by: Frank Yang --- src/cargo/ops/cargo_new.rs | 25 +++++++++++++++++++------ tests/testsuite/new.rs | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index db2156ed70e3..cdf091d01f7e 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -2,7 +2,7 @@ use crate::core::{Edition, Shell, Workspace}; use crate::util::errors::CargoResult; use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo}; use crate::util::{restricted_names, Config}; -use anyhow::Context as _; +use anyhow::{anyhow, Context as _}; use cargo_util::paths; use serde::de; use serde::Deserialize; @@ -595,9 +595,22 @@ impl IgnoreList { /// already exists. It reads the contents of the given `BufRead` and /// checks if the contents of the ignore list are already existing in the /// file. - fn format_existing(&self, existing: T, vcs: VersionControl) -> String { - // TODO: is unwrap safe? - let existing_items = existing.lines().collect::, _>>().unwrap(); + fn format_existing(&self, existing: T, vcs: VersionControl) -> CargoResult { + let mut existing_items = Vec::new(); + for (i, item) in existing.lines().enumerate() { + match item { + Ok(s) => existing_items.push(s), + Err(err) => match err.kind() { + ErrorKind::InvalidData => { + return Err(anyhow!( + "Character at line {} is invalid. Cargo only supports UTF-8.", + i + )) + } + _ => return Err(anyhow!(err)), + }, + } + } let ignore_items = match vcs { VersionControl::Hg => &self.hg_ignore, @@ -631,7 +644,7 @@ impl IgnoreList { out.push('\n'); } - out + Ok(out) } } @@ -660,7 +673,7 @@ fn write_ignore_file(base_path: &Path, list: &IgnoreList, vcs: VersionControl) - Some(io_err) if io_err.kind() == ErrorKind::NotFound => list.format_new(vcs), _ => return Err(err), }, - Ok(file) => list.format_existing(BufReader::new(file), vcs), + Ok(file) => list.format_existing(BufReader::new(file), vcs)?, }; paths::append(&fp_ignore, ignore.as_bytes())?; diff --git a/tests/testsuite/new.rs b/tests/testsuite/new.rs index 1230023c6e2a..aedb624cdfa2 100644 --- a/tests/testsuite/new.rs +++ b/tests/testsuite/new.rs @@ -509,3 +509,25 @@ fn git_default_branch() { let head = repo.find_reference("HEAD").unwrap(); assert_eq!(head.symbolic_target().unwrap(), "refs/heads/hello"); } + +#[cargo_test] +fn non_utf8_str_in_ignore_file() { + let gitignore = paths::home().join(".gitignore"); + File::create(gitignore).unwrap(); + + fs::write(paths::home().join(".gitignore"), &[0xFF, 0xFE]).unwrap(); + print!("{}", paths::home().display()); + + cargo_process(&format!("init {} --vcs git", paths::home().display())) + .with_status(101) + .with_stderr(format!( + "\ +error: Failed to create package `home` at `{}` + +Caused by: + Character at line 0 is invalid. Cargo only supports UTF-8. +", + paths::home().display() + )) + .run(); +}