Skip to content

Commit

Permalink
Avoid using 'glob' to walk templates directory.
Browse files Browse the repository at this point in the history
Previously, `dyn_templates` walked the user-provided `template_dir` path by
constructing a glob pattern prefixed with `template_dir`. If `template_dir`
contained characters recognized by the glob pattern parser, then at best the
pattern failed to parse, and at worst, incorrect directories were searched.

This commit removes the use of `glob` to walk the templates directory and
instead uses `walkdir`, obviating the issues described above.

Fixes #2627.
  • Loading branch information
SergioBenitez committed Oct 14, 2023
1 parent f950d3e commit ed5c755
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 12 deletions.
2 changes: 1 addition & 1 deletion contrib/dyn_templates/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ tera = ["tera_"]
handlebars = ["handlebars_"]

[dependencies]
glob = "0.3"
walkdir = "2.4"
notify = "6"
normpath = "1"

Expand Down
33 changes: 22 additions & 11 deletions contrib/dyn_templates/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ impl Context {
/// template engine, and store all of the initialized state in a `Context`
/// structure, which is returned if all goes well.
pub fn initialize(root: &Path, callback: &Callback) -> Option<Context> {
fn is_file_with_ext(entry: &walkdir::DirEntry, ext: &str) -> bool {
let is_file = entry.file_type().is_file();
let has_ext = entry.path().extension().map_or(false, |e| e == ext);
is_file && has_ext
}

let root = match root.normalize() {
Ok(root) => root.into_path_buf(),
Err(e) => {
Expand All @@ -35,18 +41,23 @@ impl Context {
};

let mut templates: HashMap<String, TemplateInfo> = HashMap::new();
for ext in Engines::ENABLED_EXTENSIONS {
let mut glob_path = root.join("**").join("*");
glob_path.set_extension(ext);
let glob_path = glob_path.to_str().expect("valid glob path string");
for &ext in Engines::ENABLED_EXTENSIONS {
for entry in walkdir::WalkDir::new(&root).follow_links(true) {
let entry = match entry {
Ok(entry) if is_file_with_ext(&entry, ext) => entry,
Ok(_) | Err(_) => continue,
};

for path in glob::glob(glob_path).unwrap().filter_map(Result::ok) {
let (name, data_type_str) = split_path(&root, &path);
let (name, data_type_str) = split_path(&root, entry.path());
if let Some(info) = templates.get(&*name) {
warn_!("Template name '{}' does not have a unique path.", name);
info_!("Existing path: {:?}", info.path);
info_!("Additional path: {:?}", path);
warn_!("Using existing path for template '{}'.", name);
warn_!("Template name '{}' does not have a unique source.", name);
match info.path {
Some(ref path) => info_!("Existing path: {:?}", path),
None => info_!("Existing Content-Type: {}", info.data_type),
}

info_!("Additional path: {:?}", entry.path());
warn_!("Keeping existing template '{}'.", name);
continue;
}

Expand All @@ -55,7 +66,7 @@ impl Context {
.unwrap_or(ContentType::Text);

templates.insert(name, TemplateInfo {
path: Some(path.clone()),
path: Some(entry.into_path()),
engine_ext: ext,
data_type,
});
Expand Down
10 changes: 10 additions & 0 deletions contrib/dyn_templates/tests/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,16 @@ mod tera_tests {
assert_eq!(md_rendered, Some((ContentType::HTML, ESCAPED_EXPECTED.into())));
}

#[async_test]
async fn test_globby_paths() {
use rocket::local::asynchronous::Client;

let client = Client::debug(rocket()).await.unwrap();
let req = client.get("/");
let metadata = Metadata::from_request(&req).await.unwrap();
assert!(metadata.contains_template("tera/[test]/html_test"));
}

// u128 is not supported. enable when it is.
// #[test]
// fn test_tera_u128() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends "tera/base" %}
{% block title %}{{ title }}{% endblock title %}
{% block content %}
{{ content }}
{% endblock content %}

0 comments on commit ed5c755

Please sign in to comment.