mirror of https://github.com/rwf2/Rocket.git
Canonicalize template directory before globbing.
This prevents the glob from returning paths that don't include the root template dir due to resolution of relative paths like `./foo`, preventing #1541 from reoccurring. Furthermore, this prevents misconfigured, non-existent template directories from silently passing through, instead causing an error at init-time.
This commit is contained in:
parent
aaea84d750
commit
8ee581a697
|
@ -18,7 +18,15 @@ impl Context {
|
||||||
/// Load all of the templates at `root`, initialize them using the relevant
|
/// Load all of the templates at `root`, initialize them using the relevant
|
||||||
/// template engine, and store all of the initialized state in a `Context`
|
/// template engine, and store all of the initialized state in a `Context`
|
||||||
/// structure, which is returned if all goes well.
|
/// structure, which is returned if all goes well.
|
||||||
pub fn initialize(root: PathBuf) -> Option<Context> {
|
pub fn initialize(root: &Path) -> Option<Context> {
|
||||||
|
let root = match root.canonicalize() {
|
||||||
|
Ok(root) => root,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Invalid template directory '{}': {}.", root.display(), e);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut templates: HashMap<String, TemplateInfo> = HashMap::new();
|
let mut templates: HashMap<String, TemplateInfo> = HashMap::new();
|
||||||
for ext in Engines::ENABLED_EXTENSIONS {
|
for ext in Engines::ENABLED_EXTENSIONS {
|
||||||
let mut glob_path = root.join("**").join("*");
|
let mut glob_path = root.join("**").join("*");
|
||||||
|
@ -48,13 +56,12 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
Engines::init(&templates)
|
Engines::init(&templates)
|
||||||
.map(|engines| Context { root, templates, engines } )
|
.map(|engines| Context { root: root.into(), templates, engines } )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes the file path's extension or does nothing if there is none.
|
/// Removes the file path's extension or does nothing if there is none.
|
||||||
fn remove_extension<P: AsRef<Path>>(path: P) -> PathBuf {
|
fn remove_extension(path: &Path) -> PathBuf {
|
||||||
let path = path.as_ref();
|
|
||||||
let stem = match path.file_stem() {
|
let stem = match path.file_stem() {
|
||||||
Some(stem) => stem,
|
Some(stem) => stem,
|
||||||
None => return path.to_path_buf()
|
None => return path.to_path_buf()
|
||||||
|
|
|
@ -103,7 +103,7 @@ mod context {
|
||||||
if changed {
|
if changed {
|
||||||
info_!("Change detected: reloading templates.");
|
info_!("Change detected: reloading templates.");
|
||||||
let mut ctxt = self.context_mut();
|
let mut ctxt = self.context_mut();
|
||||||
if let Some(mut new_ctxt) = Context::initialize(ctxt.root.clone()) {
|
if let Some(mut new_ctxt) = Context::initialize(&ctxt.root) {
|
||||||
match callback(&mut new_ctxt.engines) {
|
match callback(&mut new_ctxt.engines) {
|
||||||
Ok(()) => *ctxt = new_ctxt,
|
Ok(()) => *ctxt = new_ctxt,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -164,8 +164,7 @@ impl Fairing for TemplateFairing {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let root = Source::from(&*path);
|
match Context::initialize(&path) {
|
||||||
match Context::initialize(path) {
|
|
||||||
Some(mut ctxt) => {
|
Some(mut ctxt) => {
|
||||||
use rocket::{logger::PaintExt, yansi::Paint};
|
use rocket::{logger::PaintExt, yansi::Paint};
|
||||||
use crate::templates::Engines;
|
use crate::templates::Engines;
|
||||||
|
@ -174,7 +173,7 @@ impl Fairing for TemplateFairing {
|
||||||
|
|
||||||
match (self.callback)(&mut ctxt.engines) {
|
match (self.callback)(&mut ctxt.engines) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
info_!("directory: {}", Paint::white(root));
|
info_!("directory: {}", Paint::white(Source::from(&*path)));
|
||||||
info_!("engines: {:?}", Paint::white(Engines::ENABLED_EXTENSIONS));
|
info_!("engines: {:?}", Paint::white(Engines::ENABLED_EXTENSIONS));
|
||||||
Ok(rocket.manage(ContextManager::new(ctxt)))
|
Ok(rocket.manage(ContextManager::new(ctxt)))
|
||||||
}
|
}
|
||||||
|
@ -185,7 +184,10 @@ impl Fairing for TemplateFairing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Err(rocket),
|
None => {
|
||||||
|
error_!("Launch will be aborted due to failed template initialization.");
|
||||||
|
Err(rocket)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -352,7 +352,7 @@ impl Template {
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust,no_run
|
||||||
/// # extern crate rocket;
|
/// # extern crate rocket;
|
||||||
/// # extern crate rocket_contrib;
|
/// # extern crate rocket_contrib;
|
||||||
/// use std::collections::HashMap;
|
/// use std::collections::HashMap;
|
||||||
|
|
|
@ -399,10 +399,11 @@ fairings. To attach the template fairing, simply call
|
||||||
|
|
||||||
# use rocket_contrib::templates::Template;
|
# use rocket_contrib::templates::Template;
|
||||||
|
|
||||||
fn main() {
|
#[launch]
|
||||||
|
fn rocket() -> _ {
|
||||||
rocket::ignite()
|
rocket::ignite()
|
||||||
.mount("/", routes![/* .. */])
|
.mount("/", routes![/* .. */])
|
||||||
.attach(Template::fairing());
|
.attach(Template::fairing())
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue