Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strip UNC prefix on windows paths #3847

Merged
merged 2 commits into from
Feb 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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("\\\\?\\")
}