##// END OF EJS Templates
rust-pathauditor: use interior mutability for use in multi-threaded contexts...
Raphaël Gomès -
r45022:07d9fd60 default
parent child Browse files
Show More
@@ -698,7 +698,7 b" pub fn status<'a: 'c, 'b: 'c, 'c>("
698 // We walked all dirs under the roots that weren't ignored, and
698 // We walked all dirs under the roots that weren't ignored, and
699 // everything that matched was stat'ed and is already in results.
699 // everything that matched was stat'ed and is already in results.
700 // The rest must thus be ignored or under a symlink.
700 // The rest must thus be ignored or under a symlink.
701 let mut path_auditor = PathAuditor::new(root_dir);
701 let path_auditor = PathAuditor::new(root_dir);
702
702
703 for (ref filename, entry) in to_visit {
703 for (ref filename, entry) in to_visit {
704 // Report ignored items in the dmap as long as they are not
704 // Report ignored items in the dmap as long as they are not
@@ -210,7 +210,7 b' pub fn canonical_path('
210 } else {
210 } else {
211 name.to_owned()
211 name.to_owned()
212 };
212 };
213 let mut auditor = PathAuditor::new(&root);
213 let auditor = PathAuditor::new(&root);
214 if name != root && name.starts_with(&root) {
214 if name != root && name.starts_with(&root) {
215 let name = name.strip_prefix(&root).unwrap();
215 let name = name.strip_prefix(&root).unwrap();
216 auditor.audit_path(path_to_hg_path_buf(name)?)?;
216 auditor.audit_path(path_to_hg_path_buf(name)?)?;
@@ -13,13 +13,14 b' use crate::utils::{'
13 };
13 };
14 use std::collections::HashSet;
14 use std::collections::HashSet;
15 use std::path::{Path, PathBuf};
15 use std::path::{Path, PathBuf};
16 use std::sync::{Mutex, RwLock};
16
17
17 /// Ensures that a path is valid for use in the repository i.e. does not use
18 /// Ensures that a path is valid for use in the repository i.e. does not use
18 /// any banned components, does not traverse a symlink, etc.
19 /// any banned components, does not traverse a symlink, etc.
19 #[derive(Debug, Default)]
20 #[derive(Debug, Default)]
20 pub struct PathAuditor {
21 pub struct PathAuditor {
21 audited: HashSet<HgPathBuf>,
22 audited: Mutex<HashSet<HgPathBuf>>,
22 audited_dirs: HashSet<HgPathBuf>,
23 audited_dirs: RwLock<HashSet<HgPathBuf>>,
23 root: PathBuf,
24 root: PathBuf,
24 }
25 }
25
26
@@ -31,7 +32,7 b' impl PathAuditor {'
31 }
32 }
32 }
33 }
33 pub fn audit_path(
34 pub fn audit_path(
34 &mut self,
35 &self,
35 path: impl AsRef<HgPath>,
36 path: impl AsRef<HgPath>,
36 ) -> Result<(), HgPathError> {
37 ) -> Result<(), HgPathError> {
37 // TODO windows "localpath" normalization
38 // TODO windows "localpath" normalization
@@ -40,7 +41,7 b' impl PathAuditor {'
40 return Ok(());
41 return Ok(());
41 }
42 }
42 // TODO case normalization
43 // TODO case normalization
43 if self.audited.contains(path) {
44 if self.audited.lock().unwrap().contains(path) {
44 return Ok(());
45 return Ok(());
45 }
46 }
46 // AIX ignores "/" at end of path, others raise EISDIR.
47 // AIX ignores "/" at end of path, others raise EISDIR.
@@ -113,14 +114,14 b' impl PathAuditor {'
113 for index in 0..parts.len() {
114 for index in 0..parts.len() {
114 let prefix = &parts[..index + 1].join(&b'/');
115 let prefix = &parts[..index + 1].join(&b'/');
115 let prefix = HgPath::new(prefix);
116 let prefix = HgPath::new(prefix);
116 if self.audited_dirs.contains(prefix) {
117 if self.audited_dirs.read().unwrap().contains(prefix) {
117 continue;
118 continue;
118 }
119 }
119 self.check_filesystem(&prefix, &path)?;
120 self.check_filesystem(&prefix, &path)?;
120 self.audited_dirs.insert(prefix.to_owned());
121 self.audited_dirs.write().unwrap().insert(prefix.to_owned());
121 }
122 }
122
123
123 self.audited.insert(path.to_owned());
124 self.audited.lock().unwrap().insert(path.to_owned());
124
125
125 Ok(())
126 Ok(())
126 }
127 }
@@ -171,7 +172,7 b' impl PathAuditor {'
171 Ok(())
172 Ok(())
172 }
173 }
173
174
174 pub fn check(&mut self, path: impl AsRef<HgPath>) -> bool {
175 pub fn check(&self, path: impl AsRef<HgPath>) -> bool {
175 self.audit_path(path).is_ok()
176 self.audit_path(path).is_ok()
176 }
177 }
177 }
178 }
@@ -184,7 +185,7 b' mod tests {'
184
185
185 #[test]
186 #[test]
186 fn test_path_auditor() {
187 fn test_path_auditor() {
187 let mut auditor = PathAuditor::new(get_path_from_bytes(b"/tmp"));
188 let auditor = PathAuditor::new(get_path_from_bytes(b"/tmp"));
188
189
189 let path = HgPath::new(b".hg/00changelog.i");
190 let path = HgPath::new(b".hg/00changelog.i");
190 assert_eq!(
191 assert_eq!(
General Comments 0
You need to be logged in to leave comments. Login now