diff --git a/src/Cargo.lock b/src/Cargo.lock index 5fd8334e8ed9a..bd7176721095e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -613,6 +613,13 @@ dependencies = [ "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "env_sandbox" +version = "0.0.0" +dependencies = [ + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error-chain" version = "0.11.0" @@ -1692,6 +1699,7 @@ dependencies = [ "backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "env_sandbox 0.0.0", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", @@ -2480,6 +2488,7 @@ name = "syntax" version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "env_sandbox 0.0.0", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", "rustc_data_structures 0.0.0", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 2aae0f24d4849..6037808edc216 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -27,6 +27,7 @@ syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } backtrace = "0.3.3" byteorder = { version = "1.1", features = ["i128"]} +env_sandbox = { path = "../librustc_env_sandbox" } # Note that these dependencies are a lie, they're just here to get linkage to # work. diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index bb495049483ac..545e41fa5fd04 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -91,6 +91,7 @@ extern crate rustc_errors as errors; extern crate syntax_pos; extern crate jobserver; extern crate proc_macro; +extern crate env_sandbox; extern crate serialize as rustc_serialize; // used by deriving diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 456e83f4700e4..bbac05a3af5d3 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -38,6 +38,8 @@ use syntax::feature_gate::UnstableFeatures; use errors::{ColorConfig, FatalError, Handler}; +use env_sandbox::{EnvSandboxBuilder, EnvSandbox}; + use getopts; use std::collections::{BTreeMap, BTreeSet}; use std::collections::btree_map::Iter as BTreeMapIter; @@ -413,6 +415,9 @@ top_level_options!( // Remap source path prefixes in all output (messages, object files, debug, etc) remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED], edition: Edition [TRACKED], + + // Environment sandbox for process envvars and include path prefixes + env_sb: EnvSandbox [UNTRACKED], } ); @@ -593,6 +598,7 @@ pub fn basic_options() -> Options { cli_forced_thinlto_off: false, remap_path_prefix: Vec::new(), edition: DEFAULT_EDITION, + env_sb: EnvSandbox::default(), } } @@ -1653,6 +1659,34 @@ pub fn rustc_optgroups() -> Vec { "Remap source names in all output (compiler messages and output files)", "FROM=TO", ), + opt::multi_s( + "", + "env-allow", + "Allow a specific environment variable to be accessed with an env!() macro", + "ENVVAR", + ), + opt::multi_s( + "", + "env-define", + "Define an environment variable for reading with an env!() macro", + "ENVVAR=VALUE", + ), + opt::flag_s( + "", + "env-clear", + "Clear all environment, and prevent access to process environment", + ), + opt::multi_s( + "", + "include-prefix", + "Define a valid prefix for include!() macros", + "PATH", + ), + opt::flag_s( + "", + "clear-include-prefixes", + "Clear all path prefixes, disallowing access to all files", + ), ]); opts } @@ -2161,6 +2195,32 @@ pub fn build_session_options_and_crate_config( }) .collect(); + let mut env_sb = EnvSandboxBuilder::new(); + + if matches.opt_present("env-clear") { + env_sb.env_clear(); + } + for env in matches.opt_strs("env-allow") { + env_sb.env_allow(env); + } + for envvar in matches.opt_strs("env-define") { + let envvar: Vec<_> = envvar.splitn(2, '=').collect(); + if envvar.len() != 2 { + early_error(error_format, "--env-define must contain '=' between ENVVAR and VALUE"); + } + env_sb.env_define(envvar[0], envvar[1]); + } + + if matches.opt_present("clear-include-prefixes") { + env_sb.paths_clear(); + } + for pathpfx in matches.opt_strs("include-prefix") { + if let Err(err) = env_sb.path_add(pathpfx) { + early_error(error_format, &format!("--include-prefix path error: {}", err)); + } + } + let env_sb = env_sb.build(); + ( Options { crate_types, @@ -2191,6 +2251,7 @@ pub fn build_session_options_and_crate_config( cli_forced_thinlto_off: disable_thinlto, remap_path_prefix, edition, + env_sb, }, cfg, ) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3bd2bb3c8beb0..56a5f618aa4a8 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1052,7 +1052,8 @@ pub fn build_session_( }; let target_cfg = config::build_target_config(&sopts, &span_diagnostic); - let p_s = parse::ParseSess::with_span_handler(span_diagnostic, codemap); + let env_sb = Lrc::new(sopts.env_sb.clone()); + let p_s = parse::ParseSess::with_span_handler(span_diagnostic, codemap, env_sb); let default_sysroot = match sopts.maybe_sysroot { Some(_) => None, None => Some(filesearch::get_or_default_sysroot()), diff --git a/src/librustc_env_sandbox/Cargo.toml b/src/librustc_env_sandbox/Cargo.toml new file mode 100644 index 0000000000000..d9f393318097c --- /dev/null +++ b/src/librustc_env_sandbox/Cargo.toml @@ -0,0 +1,12 @@ +[package] +authors = ["The Rust Project Developers"] +name = "env_sandbox" +version = "0.0.0" + +[lib] +name = "env_sandbox" +path = "lib.rs" +crate-type = ["dylib"] + +[dev-dependencies] +tempdir = "0.3" diff --git a/src/librustc_env_sandbox/lib.rs b/src/librustc_env_sandbox/lib.rs new file mode 100644 index 0000000000000..c135a7cccec1b --- /dev/null +++ b/src/librustc_env_sandbox/lib.rs @@ -0,0 +1,282 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![deny(warnings)] + +#[cfg(test)] +extern crate tempdir; + +use std::collections::HashMap; +use std::env; +use std::fs::{self, File}; +use std::io; +use std::path::{Path, PathBuf}; + +// Set up a sandbox to access the compiler's system environment. This includes: +// - what appears in the environment (ie, visible to the `env!()` and `option_env!()` macros) +// - constrain the path prefixs files may be included from + +/// Aspects of the compiler's environment which can be sandboxed. If the field is `None`, +/// is unconstrained. +#[derive(Debug, Clone, Default)] +pub struct EnvSandbox { + /// Set of environment variables available. If a variable appears with a `None` value + /// then it means the variable can be read from the real system environment. Otherwise + /// the variable is as it has been defined here. + env: Option>>, + /// Set of paths from which files can be included. These are normalized to the real path, + /// so all files being opened are also opened via normalized real paths. + paths: Option>, +} + +/// Builder for an `EnvSandbox` +pub struct EnvSandboxBuilder(EnvSandbox); + +impl EnvSandboxBuilder { + /// Construct a new `EnvSandboxBuilder`. + pub fn new() -> Self { + EnvSandboxBuilder(EnvSandbox { + env: None, + paths: None, + }) + } + + fn env_add_filter(&mut self, var: K, val: Option) + where + String: From, + String: From, + { + let var = String::from(var); + let val = val.map(String::from); + + let mut env = self.0.env.take().unwrap_or(HashMap::new()); + + env.insert(var, val); + + self.0.env = Some(env); + } + + /// Define a new name->value mapping + pub fn env_define(&mut self, var: K, val: V) -> &mut Self + where + String: From, + String: From, + { + self.env_add_filter(var, Some(val)); + self + } + + /// Allow a give name to be accessed from the environment + pub fn env_allow(&mut self, var: K) -> &mut Self + where + String: From, + { + self.env_add_filter::<_, String>(var, None); + self + } + + /// Set up an empty mapping, prohibiting access to the process environment without + /// defining any new variables. + pub fn env_clear(&mut self) -> &mut Self { + self.0.env = Some(HashMap::new()); + self + } + + /// Clear all path prefixes, leaving no valid prefixes. This prevents all file access. + pub fn paths_clear(&mut self) -> &mut Self { + self.0.paths = Some(Vec::new()); + self + } + + /// Add a path prefix to the allowed set. The path must exist so that it can + /// be canonicalized. + pub fn path_add>(&mut self, path: P) -> io::Result<&mut Self> { + let path = path.as_ref(); + let path = fs::canonicalize(path)?; + + let mut paths = self.0.paths.take().unwrap_or(Vec::new()); + paths.push(path); + self.0.paths = Some(paths); + + Ok(self) + } + + /// Construct an `EnvSandbox` from the builder + pub fn build(self) -> EnvSandbox { + self.0 + } +} + +impl EnvSandbox { + /// Get an environment variable, either from the real environment + /// or from the locally defined sandbox variables. + pub fn env_get(&self, var: &str) -> Option { + match &self.env { + &None => env::var(var).ok(), + &Some(ref map) => match map.get(var) { + None => None, + Some(&Some(ref val)) => Some(val.to_string()), + Some(&None) => env::var(var).ok(), + }, + } + } + + /// Return true if a given path has a valid prefix. Fails if the path + /// can't be canonicalized. + pub fn path_ok>(&self, path: P) -> io::Result { + let path = path.as_ref(); + let fullpath = fs::canonicalize(path)?; + + let ret = if let Some(ref paths) = self.paths { + paths.iter().any(|p| fullpath.starts_with(p)) + } else { + true + }; + Ok(ret) + } + + /// Map a path to itself if it has a valid prefix, otherwise return a suitable + /// error. + pub fn path_lookup

(&self, path: P) -> io::Result

+ where + P: AsRef, + { + if self.path_ok(&path)? { + Ok(path) + } else { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + "path does not have a valid prefix", + )) + } + } + + /// Open a path for reading if it has a valid prefix. + pub fn path_open>(&self, path: P) -> io::Result { + File::open(self.path_lookup(path)?) + } +} + +#[cfg(test)] +mod test { + use super::*; + + use std::env; + use tempdir::TempDir; + + #[test] + fn test_env() { + env::set_var("ZUBZUB", "ZIBZIB"); + + let sb = EnvSandbox::default(); + + assert_eq!(env::var("ZUBZUB"), Ok("ZIBZIB".to_string())); + assert_eq!(sb.env_get("ZUBZUB"), Some("ZIBZIB".to_string())); + } + + #[test] + fn test_env_filter() { + let mut sb = EnvSandboxBuilder::new(); + + sb.env_define("FOO", "BAR"); + + let sb = sb.build(); + + assert_eq!(sb.env_get("FOO"), Some("BAR".to_string())); + assert_eq!(sb.env_get("BLAHBLAH"), None); + } + + #[test] + fn test_env_allow() { + let mut sb = EnvSandboxBuilder::new(); + + sb.env_define("FOO", "BAR") + .env_allow("BLOP") + .env_allow("GLUB"); + + let sb = sb.build(); + + env::set_var("ZUBZUB", "ZIBZIB"); + env::set_var("BLOP", "Blub"); + env::remove_var("GLUB"); + + assert_eq!(sb.env_get("FOO"), Some("BAR".to_string())); + assert_eq!(sb.env_get("ZUBZUB"), None); + assert_eq!(sb.env_get("BLOP"), Some("Blub".to_string())); + assert_eq!(sb.env_get("GLUB"), None); + } + + #[test] + fn test_env_clear() { + let mut sb = EnvSandboxBuilder::new(); + + sb.env_define("FOO", "BAR") + .env_allow("BLOP") + .env_allow("GLUB") + .env_clear(); + + let sb = sb.build(); + + env::set_var("ZUBZUB", "ZIBZIB"); + env::set_var("BLOP", "Blub"); + env::remove_var("GLUB"); + + assert_eq!(sb.env_get("FOO"), None); + assert_eq!(sb.env_get("ZUBZUB"), None); + assert_eq!(sb.env_get("BLOP"), None); + assert_eq!(sb.env_get("GLUB"), None); + } + + #[test] + fn test_path() { + let dir = TempDir::new("test").expect("tempdir failed"); + let subdir = dir.path().join("subdir"); + fs::create_dir(&subdir).expect("subdir failed"); + + let sb = EnvSandbox::default(); + + assert!(sb.path_ok(&dir).unwrap()); + assert!(sb.path_ok(dir.path().parent().unwrap()).unwrap()); + assert!(sb.path_ok(&subdir).unwrap()); + assert!(sb.path_ok("/").unwrap()); + } + + #[test] + fn test_path_filter() { + let dir = TempDir::new("test").expect("tempdir failed"); + let subdir = dir.path().join("subdir"); + fs::create_dir(&subdir).expect("subdir failed"); + + let mut sb = EnvSandboxBuilder::new(); + sb.path_add(&dir).unwrap(); + let sb = sb.build(); + + assert!(sb.path_ok(&dir).unwrap()); + assert!(!sb.path_ok(dir.path().parent().unwrap()).unwrap()); + assert!(sb.path_ok(&subdir).unwrap()); + assert!(!sb.path_ok("/").unwrap()); + } + + #[test] + fn test_path_clear() { + let dir = TempDir::new("test").expect("tempdir failed"); + let subdir = dir.path().join("subdir"); + fs::create_dir(&subdir).expect("subdir failed"); + + let mut sb = EnvSandboxBuilder::new(); + sb.path_add(&dir).unwrap(); + sb.paths_clear(); + let sb = sb.build(); + + assert!(!sb.path_ok(&dir).unwrap()); + assert!(!sb.path_ok(dir.path().parent().unwrap()).unwrap()); + assert!(!sb.path_ok(&subdir).unwrap()); + assert!(!sb.path_ok("/").unwrap()); + } +} diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 8c24f36615bd2..6120eb68c9eb1 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -17,3 +17,4 @@ syntax_pos = { path = "../libsyntax_pos" } rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } rustc_errors = { path = "../librustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } +env_sandbox = { path = "../librustc_env_sandbox" } \ No newline at end of file diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index d6dce63ea5e4b..d1d0c456c7675 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -21,7 +21,6 @@ use symbol::Symbol; use tokenstream; use util::small_vector::SmallVector; -use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; use rustc_data_structures::sync::Lrc; @@ -99,7 +98,18 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T None => return DummyResult::expr(sp), }; // The file will be added to the code map by the parser - let path = res_rel_file(cx, sp, file); + let path = res_rel_file(cx, sp, file.clone()); + let env_sb = cx.parse_sess().env_sandbox(); + let path = match env_sb.path_lookup(&path) { + Ok(path) => path, + Err(e) => { + cx.span_err(sp, + &format!("couldn't read {}: {}", + file, + e)); + return DummyResult::expr(sp); + } + }; let directory_ownership = DirectoryOwnership::Owned { relative: None }; let p = parse::new_sub_parser_from_file(cx.parse_sess(), &path, directory_ownership, None, sp); @@ -136,9 +146,10 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenT Some(f) => f, None => return DummyResult::expr(sp) }; + let env_sb = cx.parse_sess().env_sandbox(); let file = res_rel_file(cx, sp, file); let mut bytes = Vec::new(); - match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) { + match env_sb.path_open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) { Ok(..) => {} Err(e) => { cx.span_err(sp, @@ -171,9 +182,10 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::Toke Some(f) => f, None => return DummyResult::expr(sp) }; + let env_sb = cx.parse_sess().env_sandbox(); let file = res_rel_file(cx, sp, file); let mut bytes = Vec::new(); - match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) { + match env_sb.path_open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) { Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index ad98e2a6b71ad..ea445171be44b 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -40,6 +40,7 @@ pub extern crate rustc_errors as errors; extern crate syntax_pos; extern crate rustc_data_structures; #[macro_use] extern crate scoped_tls; +extern crate env_sandbox; extern crate serialize as rustc_serialize; // used by deriving diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 22a0261d8c6b1..54525d5828d88 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1787,6 +1787,7 @@ mod tests { use diagnostics::plugin::ErrorMap; use rustc_data_structures::sync::Lock; use with_globals; + use env_sandbox::EnvSandbox; fn mk_sess(cm: Lrc) -> ParseSess { let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), Some(cm.clone()), @@ -1802,6 +1803,7 @@ mod tests { raw_identifier_spans: Lock::new(Vec::new()), registered_diagnostics: Lock::new(ErrorMap::new()), non_modrs_mods: Lock::new(vec![]), + env_sandbox: Lrc::new(EnvSandbox::default()), } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 0397c3297db0a..adcc58fd36af7 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -22,6 +22,7 @@ use str::char_at; use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; use diagnostics::plugin::ErrorMap; +use env_sandbox::EnvSandbox; use std::collections::HashSet; use std::iter; @@ -57,6 +58,7 @@ pub struct ParseSess { /// Used to determine and report recursive mod inclusions included_mod_stack: Lock>, code_map: Lrc, + env_sandbox: Lrc, } impl ParseSess { @@ -66,10 +68,12 @@ impl ParseSess { true, false, Some(cm.clone())); - ParseSess::with_span_handler(handler, cm) + let env_sb = Lrc::new(EnvSandbox::default()); + ParseSess::with_span_handler(handler, cm, env_sb) } - pub fn with_span_handler(handler: Handler, code_map: Lrc) -> ParseSess { + pub fn with_span_handler(handler: Handler, code_map: Lrc, env_sandbox: Lrc) + -> ParseSess { ParseSess { span_diagnostic: handler, unstable_features: UnstableFeatures::from_environment(), @@ -80,12 +84,17 @@ impl ParseSess { included_mod_stack: Lock::new(vec![]), code_map, non_modrs_mods: Lock::new(vec![]), + env_sandbox, } } pub fn codemap(&self) -> &CodeMap { &self.code_map } + + pub fn env_sandbox(&self) -> &EnvSandbox { + &self.env_sandbox + } } #[derive(Clone)] diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index 4e1af108ab4fa..90a06d5f399a7 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -21,8 +21,6 @@ use syntax::symbol::{keywords, Symbol}; use syntax_pos::Span; use syntax::tokenstream; -use std::env; - pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) @@ -33,8 +31,10 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, }; let sp = sp.apply_mark(cx.current_expansion.mark); - let e = match env::var(&*var.as_str()) { - Err(..) => { + let env_sb = cx.parse_sess().env_sandbox(); + + let e = match env_sb.env_get(&*var.as_str()) { + None => { let lt = cx.lifetime(sp, keywords::StaticLifetime.ident()); cx.expr_path(cx.path_all(sp, true, @@ -46,7 +46,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, ast::Mutability::Immutable)], Vec::new())) } - Ok(s) => { + Some(s) => { cx.expr_call_global(sp, cx.std_path(&["option", "Option", "Some"]), vec![cx.expr_str(sp, Symbol::intern(&s))]) @@ -68,6 +68,8 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, Some(exprs) => exprs.into_iter(), }; + let env_sb = cx.parse_sess().env_sandbox(); + let var = match expr_to_string(cx, exprs.next().unwrap(), "expected string literal") { None => return DummyResult::expr(sp), Some((v, _style)) => v, @@ -87,12 +89,12 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, return DummyResult::expr(sp); } - let e = match env::var(&*var.as_str()) { - Err(_) => { + let e = match env_sb.env_get(&*var.as_str()) { + None => { cx.span_err(sp, &msg.as_str()); cx.expr_usize(sp, 0) } - Ok(s) => cx.expr_str(sp, Symbol::intern(&s)), + Some(s) => cx.expr_str(sp, Symbol::intern(&s)), }; MacEager::expr(e) } diff --git a/src/test/compile-fail/sb-fixtures/a/a.in b/src/test/compile-fail/sb-fixtures/a/a.in new file mode 100644 index 0000000000000..6d8b18077cc99 --- /dev/null +++ b/src/test/compile-fail/sb-fixtures/a/a.in @@ -0,0 +1 @@ +File A diff --git a/src/test/compile-fail/sb-fixtures/b/b.in b/src/test/compile-fail/sb-fixtures/b/b.in new file mode 100644 index 0000000000000..c512b6c64656b --- /dev/null +++ b/src/test/compile-fail/sb-fixtures/b/b.in @@ -0,0 +1 @@ +File B diff --git a/src/test/compile-fail/sb-inc-limit.rs b/src/test/compile-fail/sb-inc-limit.rs new file mode 100644 index 0000000000000..436efde0cf6ae --- /dev/null +++ b/src/test/compile-fail/sb-inc-limit.rs @@ -0,0 +1,17 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test to see how file sandboxing is working. This blocks all includes. +// compile-flags:--include-prefix {{src-base}}/sb-fixtures/a + +fn main() { + let _ = include_str!("sb-fixtures/a/a.in"); + let _ = include_str!("sb-fixtures/b/b.in"); //~ERROR: path does not have a valid prefix +} diff --git a/src/test/compile-fail/sb-inc-none.rs b/src/test/compile-fail/sb-inc-none.rs new file mode 100644 index 0000000000000..cc71ef68f5519 --- /dev/null +++ b/src/test/compile-fail/sb-inc-none.rs @@ -0,0 +1,27 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test to see how file sandboxing is working. This blocks all includes. +// compile-flags:--clear-include-prefixes +// revisions: include include_str include_bytes + +fn main() { + #[cfg(include)] + include!("sb-fixtures/a/a.in"); + //[include]~^ERROR path does not have a valid prefix + + #[cfg(include_str)] + let _ = include_str!("sb-fixtures/a/a.in"); + //[include_str]~^ERROR path does not have a valid prefix + + #[cfg(include_bytes)] + let _ = include_bytes!("sb-fixtures/a/a.in"); + //[include_bytes]~^ERROR path does not have a valid prefix +} diff --git a/src/test/run-pass/sb-env.rs b/src/test/run-pass/sb-env.rs new file mode 100644 index 0000000000000..3d0a690c0af45 --- /dev/null +++ b/src/test/run-pass/sb-env.rs @@ -0,0 +1,22 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test to see how environment sandboxing is working +// rustc-env:BLOBBIE=FOO +// rustc-env:FOOBIE=BAR +// rustc-env:THINGY=OLD +// compile-flags:--env-allow BLOBBIE --env-define ZIPPIE=BLARG --env-define THINGY=NEW + +fn main() { + assert_eq!(option_env!("BLOBBIE"), Some("FOO")); // actual environment, allowed to be seen + assert_eq!(option_env!("ZIPPIE"), Some("BLARG")); // defined on command-line + assert_eq!(option_env!("THINGY"), Some("NEW")); // overridden on command-line + assert_eq!(option_env!("FOOBIE"), None); // actual environment, but not allowed to be seen +} diff --git a/src/test/run-pass/sb-fixtures/a/a.in b/src/test/run-pass/sb-fixtures/a/a.in new file mode 100644 index 0000000000000..6d8b18077cc99 --- /dev/null +++ b/src/test/run-pass/sb-fixtures/a/a.in @@ -0,0 +1 @@ +File A diff --git a/src/test/run-pass/sb-fixtures/b/b.in b/src/test/run-pass/sb-fixtures/b/b.in new file mode 100644 index 0000000000000..c512b6c64656b --- /dev/null +++ b/src/test/run-pass/sb-fixtures/b/b.in @@ -0,0 +1 @@ +File B diff --git a/src/test/run-pass/sb-inc.rs b/src/test/run-pass/sb-inc.rs new file mode 100644 index 0000000000000..207c23f6376ec --- /dev/null +++ b/src/test/run-pass/sb-inc.rs @@ -0,0 +1,18 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test to see how environment sandboxing is working +// compile-flags:--include-prefix {{src-base}}/sb-fixtures/a +// compile-flags:--include-prefix {{src-base}}/sb-fixtures/b/b.in + +fn main() { + assert_eq!(include_str!("sb-fixtures/a/a.in"), "File A\n"); + assert_eq!(include_str!("sb-fixtures/b/b.in"), "File B\n"); +} diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 85434bb8a69b8..b8c09901e55e0 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1535,6 +1535,7 @@ impl<'test> TestCx<'test> { } } + logv(self.config, format!("rustc env {:?}", self.props.rustc_env)); rustc.envs(self.props.rustc_env.clone()); self.compose_and_run( rustc,