diff options
Diffstat (limited to 'components/embedder_traits/resources.rs')
-rw-r--r-- | components/embedder_traits/resources.rs | 102 |
1 files changed, 61 insertions, 41 deletions
diff --git a/components/embedder_traits/resources.rs b/components/embedder_traits/resources.rs index c5b77210d0b..04d3b0a706b 100644 --- a/components/embedder_traits/resources.rs +++ b/components/embedder_traits/resources.rs @@ -16,11 +16,6 @@ pub fn set(reader: Box<dyn ResourceReaderMethods + Sync + Send>) { *RES.write().unwrap() = Some(reader); } -pub fn set_for_tests() { - static ONCE: Once = Once::new(); - ONCE.call_once(|| set(resources_for_tests())); -} - pub fn read_bytes(res: Resource) -> Vec<u8> { RES.read() .unwrap() @@ -66,57 +61,82 @@ pub enum Resource { CrashHTML, } +impl Resource { + pub fn filename(&self) -> &'static str { + match self { + Resource::Preferences => "prefs.json", + Resource::BluetoothBlocklist => "gatt_blocklist.txt", + Resource::DomainList => "public_domains.txt", + Resource::HstsPreloadList => "hsts_preload.json", + Resource::BadCertHTML => "badcert.html", + Resource::NetErrorHTML => "neterror.html", + Resource::UserAgentCSS => "user-agent.css", + Resource::ServoCSS => "servo.css", + Resource::PresentationalHintsCSS => "presentational-hints.css", + Resource::QuirksModeCSS => "quirks-mode.css", + Resource::RippyPNG => "rippy.png", + Resource::MediaControlsCSS => "media-controls.css", + Resource::MediaControlsJS => "media-controls.js", + Resource::CrashHTML => "crash.html", + } + } +} + pub trait ResourceReaderMethods { fn read(&self, res: Resource) -> Vec<u8>; fn sandbox_access_files(&self) -> Vec<PathBuf>; fn sandbox_access_files_dirs(&self) -> Vec<PathBuf>; } +// Can’t #[cfg(test)] the following because it breaks tests in dependent crates. + +pub fn set_for_tests() { + static ONCE: Once = Once::new(); + ONCE.call_once(|| set(resources_for_tests())); +} + +lazy_static::lazy_static! { + static ref CMD_RESOURCE_DIR: std::sync::Mutex<Option<PathBuf>> = std::sync::Mutex::new(None); +} + +fn resources_dir_path_for_tests() -> PathBuf { + // This needs to be called before the process is sandboxed + // as we only give permission to read inside the resources directory, + // not the permissions the "search" for the resources directory. + let mut dir = CMD_RESOURCE_DIR.lock().unwrap(); + if let Some(ref path) = *dir { + return PathBuf::from(path); + } + + // Try ./resources in the current directory, then each of its ancestors. + let mut path = std::env::current_dir().unwrap(); + loop { + path.push("resources"); + if path.is_dir() { + *dir = Some(path); + return dir.clone().unwrap(); + } + path.pop(); + + if !path.pop() { + panic!("Can't find resources directory") + } + } +} + fn resources_for_tests() -> Box<dyn ResourceReaderMethods + Sync + Send> { - use std::env; - use std::fs::File; - use std::io::Read; struct ResourceReader; impl ResourceReaderMethods for ResourceReader { fn sandbox_access_files(&self) -> Vec<PathBuf> { vec![] } fn sandbox_access_files_dirs(&self) -> Vec<PathBuf> { - vec![] + vec![resources_dir_path_for_tests()] } fn read(&self, file: Resource) -> Vec<u8> { - let file = match file { - Resource::Preferences => "prefs.json", - Resource::BluetoothBlocklist => "gatt_blocklist.txt", - Resource::DomainList => "public_domains.txt", - Resource::HstsPreloadList => "hsts_preload.json", - Resource::BadCertHTML => "badcert.html", - Resource::NetErrorHTML => "neterror.html", - Resource::UserAgentCSS => "user-agent.css", - Resource::ServoCSS => "servo.css", - Resource::PresentationalHintsCSS => "presentational-hints.css", - Resource::QuirksModeCSS => "quirks-mode.css", - Resource::RippyPNG => "rippy.png", - Resource::MediaControlsCSS => "media-controls.css", - Resource::MediaControlsJS => "media-controls.js", - Resource::CrashHTML => "crash.html", - }; - let mut path = env::current_exe().unwrap(); - path = path.canonicalize().unwrap(); - while path.pop() { - path.push("resources"); - if path.is_dir() { - break; - } - path.pop(); - } - path.push(file); - let mut buffer = vec![]; - File::open(path) - .expect(&format!("Can't find file: {}", file)) - .read_to_end(&mut buffer) - .expect("Can't read file"); - buffer + let mut path = resources_dir_path_for_tests(); + path.push(file.filename()); + std::fs::read(path).expect("Can't read file") } } Box::new(ResourceReader) |