Make VFS join methods fallible

This commit is contained in:
Jonas Schievink 2020-06-26 16:25:08 +02:00
parent 38cd1b70e8
commit 72fe70f2f8
4 changed files with 27 additions and 9 deletions

View file

@ -334,6 +334,22 @@ fn module_resolution_relative_path_2() {
"###); "###);
} }
#[test]
fn module_resolution_relative_path_outside_root() {
let map = def_map(
r###"
//- /main.rs
#[path="../../../../../outside.rs"]
mod foo;
"###,
);
assert_snapshot!(map, @r###"
crate
"###);
}
#[test] #[test]
fn module_resolution_explicit_path_mod_rs_2() { fn module_resolution_explicit_path_mod_rs_2() {
let map = def_map( let map = def_map(

View file

@ -213,7 +213,7 @@ impl GlobalStateSnapshot {
pub(crate) fn anchored_path(&self, file_id: FileId, path: &str) -> Url { pub(crate) fn anchored_path(&self, file_id: FileId, path: &str) -> Url {
let mut base = self.vfs.read().0.file_path(file_id); let mut base = self.vfs.read().0.file_path(file_id);
base.pop(); base.pop();
let path = base.join(path); let path = base.join(path).unwrap();
let path = path.as_path().unwrap(); let path = path.as_path().unwrap();
url_from_abs_path(&path) url_from_abs_path(&path)
} }

View file

@ -18,7 +18,7 @@ impl FileSet {
pub fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> { pub fn resolve_path(&self, anchor: FileId, path: &str) -> Option<FileId> {
let mut base = self.paths[&anchor].clone(); let mut base = self.paths[&anchor].clone();
base.pop(); base.pop();
let path = base.join(path); let path = base.join(path)?;
let res = self.files.get(&path).copied(); let res = self.files.get(&path).copied();
res res
} }

View file

@ -22,15 +22,15 @@ impl VfsPath {
VfsPathRepr::VirtualPath(_) => None, VfsPathRepr::VirtualPath(_) => None,
} }
} }
pub fn join(&self, path: &str) -> VfsPath { pub fn join(&self, path: &str) -> Option<VfsPath> {
match &self.0 { match &self.0 {
VfsPathRepr::PathBuf(it) => { VfsPathRepr::PathBuf(it) => {
let res = it.join(path).normalize(); let res = it.join(path).normalize();
VfsPath(VfsPathRepr::PathBuf(res)) Some(VfsPath(VfsPathRepr::PathBuf(res)))
} }
VfsPathRepr::VirtualPath(it) => { VfsPathRepr::VirtualPath(it) => {
let res = it.join(path); let res = it.join(path)?;
VfsPath(VfsPathRepr::VirtualPath(res)) Some(VfsPath(VfsPathRepr::VirtualPath(res)))
} }
} }
} }
@ -101,13 +101,15 @@ impl VirtualPath {
self.0 = self.0[..pos].to_string(); self.0 = self.0[..pos].to_string();
true true
} }
fn join(&self, mut path: &str) -> VirtualPath { fn join(&self, mut path: &str) -> Option<VirtualPath> {
let mut res = self.clone(); let mut res = self.clone();
while path.starts_with("../") { while path.starts_with("../") {
assert!(res.pop()); if !res.pop() {
return None;
}
path = &path["../".len()..] path = &path["../".len()..]
} }
res.0 = format!("{}/{}", res.0, path); res.0 = format!("{}/{}", res.0, path);
res Some(res)
} }
} }