From 01bb1e67da18498e188f0b1f7a9b5fd6a86c7a47 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Thu, 27 Oct 2022 21:33:19 -0700 Subject: [PATCH] workspace: fail gracefully on non-Unicode paths --- lib/src/workspace.rs | 19 ++++++++++++++++--- src/cli_util.rs | 3 +++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/src/workspace.rs b/lib/src/workspace.rs index 2865e9481..9bd0853c1 100644 --- a/lib/src/workspace.rs +++ b/lib/src/workspace.rs @@ -31,6 +31,8 @@ use crate::working_copy::WorkingCopy; pub enum WorkspaceInitError { #[error("The destination repo ({0}) already exists")] DestinationExists(PathBuf), + #[error("Repo path could not be interpreted as Unicode text")] + NonUnicodePath, #[error(transparent)] Path(#[from] PathError), } @@ -41,6 +43,8 @@ pub enum WorkspaceLoadError { RepoDoesNotExist(PathBuf), #[error("There is no Jujutsu repo in {0}")] NoWorkspaceHere(PathBuf), + #[error("Repo path could not be interpreted as Unicode text")] + NonUnicodePath, #[error(transparent)] Path(#[from] PathError), } @@ -173,7 +177,12 @@ impl Workspace { let repo_file_path = jj_dir.join("repo"); let mut repo_file = File::create(&repo_file_path).context(&repo_file_path)?; repo_file - .write_all(repo_dir.to_str().unwrap().as_bytes()) + .write_all( + repo_dir + .to_str() + .ok_or(WorkspaceInitError::NonUnicodePath)? + .as_bytes(), + ) .context(&repo_file_path)?; let (working_copy, repo) = @@ -189,7 +198,10 @@ impl Workspace { ) -> Result { let jj_dir = find_jj_dir(workspace_path) .ok_or_else(|| WorkspaceLoadError::NoWorkspaceHere(workspace_path.to_owned()))?; - let workspace_root = jj_dir.parent().unwrap().to_owned(); + let workspace_root = jj_dir + .parent() + .ok_or(WorkspaceLoadError::NonUnicodePath)? + .to_owned(); let mut repo_dir = jj_dir.join("repo"); // If .jj/repo is a file, then we interpret its contents as a relative path to // the actual repo directory (typically in another workspace). @@ -197,7 +209,8 @@ impl Workspace { let mut repo_file = File::open(&repo_dir).context(&repo_dir)?; let mut buf = Vec::new(); repo_file.read_to_end(&mut buf).context(&repo_dir)?; - let repo_path_str = String::from_utf8(buf).unwrap(); + let repo_path_str = + String::from_utf8(buf).map_err(|_| WorkspaceLoadError::NonUnicodePath)?; repo_dir = jj_dir .join(&repo_path_str) .canonicalize() diff --git a/src/cli_util.rs b/src/cli_util.rs index ed2a0aa36..d864eeaf7 100644 --- a/src/cli_util.rs +++ b/src/cli_util.rs @@ -233,6 +233,9 @@ jj init --git-repo=."; Err(WorkspaceLoadError::Path(e)) => { return Err(CommandError::UserError(format!("{}: {}", e, e.error))); } + Err(e @ WorkspaceLoadError::NonUnicodePath) => { + return Err(CommandError::UserError(e.to_string())); + } }; let repo_loader = workspace.repo_loader(); let op_heads = resolve_op_for_load(