Skip to content

Commit

Permalink
strip UNC prefix on windows paths (vercel/turborepo#3847)
Browse files Browse the repository at this point in the history
  • Loading branch information
ForsakenHarmony authored Feb 17, 2023
1 parent f1a3e8c commit cc6d137
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 33 deletions.
1 change: 1 addition & 0 deletions crates/next-dev/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ rustls-tls = ["next-core/rustls-tls"]
anyhow = { version = "1.0.47", features = ["backtrace"] }
clap = { version = "4.0.18", features = ["derive", "env"], optional = true }
console-subscriber = { version = "0.1.8", optional = true }
dunce = "1.0.3"
futures = "0.3.25"
mime = "0.3.16"
next-core = { path = "../next-core" }
Expand Down
5 changes: 3 additions & 2 deletions crates/next-dev/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::{

use anyhow::{anyhow, Context, Result};
use devserver_options::DevServerOptions;
use dunce::canonicalize;
use next_core::{
create_app_source, create_page_source, create_web_entry_source, env::load_env,
manifest::DevManifestContentSource, next_config::load_next_config,
Expand Down Expand Up @@ -421,15 +422,15 @@ pub async fn start_server(options: &DevServerOptions) -> Result<()> {
let dir = options
.dir
.as_ref()
.map(|dir| dir.canonicalize())
.map(|dir| canonicalize(dir))
.unwrap_or_else(current_dir)
.context("project directory can't be found")?
.to_str()
.context("project directory contains invalid characters")?
.to_string();

let root_dir = if let Some(root) = options.root.as_ref() {
root.canonicalize()
canonicalize(root)
.context("root directory can't be found")?
.to_str()
.context("root directory contains invalid characters")?
Expand Down
1 change: 1 addition & 0 deletions crates/turbo-tasks-fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ auto-hash-map = { path = "../auto-hash-map" }
bitflags = "1.3.2"
bytes = "1.1.0"
concurrent-queue = "1.2.2"
dunce = "1.0.3"
futures = "0.3.25"
futures-retry = "0.6.0"
include_dir = { version = "0.7.2", features = ["nightly"] }
Expand Down
5 changes: 3 additions & 2 deletions crates/turbo-tasks-fs/src/embed/file.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use std::path::PathBuf;

use anyhow::{Context, Result};
use dunce::canonicalize;

use crate::{DiskFileSystemVc, File, FileContentVc, FileSystem};

#[turbo_tasks::function]
pub async fn content_from_relative_path(package_path: &str, path: &str) -> Result<FileContentVc> {
let package_path = PathBuf::from(package_path);
let resolved_path = package_path.join(path);
let resolved_path = std::fs::canonicalize(&resolved_path)
.context("failed to canonicalize embedded file path")?;
let resolved_path =
canonicalize(&resolved_path).context("failed to canonicalize embedded file path")?;
let root_path = resolved_path.parent().unwrap();
let path = resolved_path.file_name().unwrap().to_str().unwrap();

Expand Down
21 changes: 7 additions & 14 deletions crates/turbo-tasks-fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use std::{
use anyhow::{anyhow, bail, Context, Result};
use auto_hash_map::AutoMap;
use bitflags::bitflags;
use dunce::simplified;
use glob::GlobVc;
use invalidator_map::InvalidatorMap;
use jsonc_parser::{parse_to_serde_value, ParseOptions};
Expand All @@ -58,8 +59,6 @@ use turbo_tasks_hash::hash_xxh3_hash64;
use util::{join_path, normalize_path, sys_to_unix, unix_to_sys};

use self::{json::UnparseableJson, mutex_map::MutexMap};
#[cfg(target_family = "windows")]
use crate::util::is_windows_raw_path;
use crate::{
attach::AttachedFileSystemVc,
retry::{retry_blocking, retry_future},
Expand Down Expand Up @@ -270,7 +269,8 @@ impl DiskFileSystem {
}

pub async fn to_sys_path(&self, fs_path: FileSystemPathVc) -> Result<PathBuf> {
let path = Path::new(&self.root);
// just in case there's a windows unc path prefix we remove it with `dunce`
let path = simplified(Path::new(&self.root));
let fs_path = fs_path.await?;
Ok(if fs_path.path.is_empty() {
path.to_path_buf()
Expand Down Expand Up @@ -419,18 +419,11 @@ impl FileSystem for DiskFileSystem {
// strip the root from the path, it serves two purpose
// 1. ensure the linked path is under the root
// 2. strip the root path if the linked path is absolute
#[cfg(target_family = "windows")]
let result = {
let root_path = Path::new(&self.root);
if is_windows_raw_path(root_path) && !is_windows_raw_path(&file) {
file.strip_prefix(Path::new(&self.root[4..]))
} else {
file.strip_prefix(root_path)
}
};
//
// we use `dunce::simplify` to strip a potential UNC prefix on windows, on any
// other OS this gets compiled away
let result = simplified(&file).strip_prefix(simplified(Path::new(&self.root)));

#[cfg(not(target_family = "windows"))]
let result = file.strip_prefix(Path::new(&self.root));
let relative_to_root_path = match result {
Ok(file) => PathBuf::from(sys_to_unix(&file.to_string_lossy()).as_ref()),
Err(_) => return Ok(LinkContent::Invalid.cell()),
Expand Down
15 changes: 0 additions & 15 deletions crates/turbo-tasks-fs/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::borrow::Cow;
#[cfg(target_family = "windows")]
use std::path::Path;

/// Joins two /-separated paths into a normalized path.
/// Paths are concatenated with /.
Expand Down Expand Up @@ -112,16 +110,3 @@ pub fn normalize_request(str: &str) -> String {
}
seqments.join("/")
}

#[cfg(target_family = "windows")]
/// Checks if the path has the `\\?\` prefix which "tells the Windows APIs to
/// disable all string parsing and to send the string that follows it straight
/// to the file system."
///
/// See [Win32 File Namespaces](https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#win32-file-namespaces)
pub fn is_windows_raw_path(path: impl AsRef<Path>) -> bool {
// `Path::new("\\\\?\\D:\\workspace\\turbo-tooling").starts_with("\\\\?\\")` is
// `false`.
// So we use `String::starts_with` here
path.as_ref().to_string_lossy().starts_with("\\\\?\\")
}

0 comments on commit cc6d137

Please sign in to comment.