Skip to content

Switch to std::path::absolute to avoid symlinking template paths#720

Merged
GuillaumeGomez merged 6 commits intoaskama-rs:mainfrom
kaepr:fix-path-ext-miss
Apr 1, 2026
Merged

Switch to std::path::absolute to avoid symlinking template paths#720
GuillaumeGomez merged 6 commits intoaskama-rs:mainfrom
kaepr:fix-path-ext-miss

Conversation

@kaepr
Copy link
Copy Markdown
Contributor

@kaepr kaepr commented Mar 26, 2026

In our build system, we use content addressable storage, where the template files lose their extensions. For e.g. for the below

#[derive(Template)]
#[template(path = "sidebar.html")]

Which might become a file such as

path/to/some/location/YGBgcnVzdAojW2Rlcml2ZShUZW1wbGF0ZSldCiNbdGVtcGxhdGUocGF0aCA9ICJzaWRlYmFyLmh0bWwiKV0KUmFuZG9tCmBgYAo=

As we have lost the extension, it defaults to empty strings here. So instead of applying the default HTML filter to escape symbols, it defaults to None.

The fix suggested switches to absolute, which avoids symlinking the template path. This preserves the file extension and the correct escaper is applied.

I am seeing other issues such as #288, #708 which also revolve around absolute / canonical paths. All the tests do pass with this change, but there are other workarounds to preserve the file path, which can possibly avoid affecting their systems.

For e.g. storing the file extension before passing config.find_template in the TemplateInput::new.

        } = args;

        let raw_ext = match &source {
            #[cfg(feature = "external-sources")]
            Source::Path(p) => Path::new(p.as_ref()).extension().and_then(|s| s.to_str()),
            _ => None,
        };

        // ...
        // Match extension against defined output formats

        let escaping = escaping
            .as_deref()
            .or_else(|| path.extension().and_then(|s| s.to_str()))
            .or_else(|| raw_ext) // it might be better to have this check first ?
            .unwrap_or_default();

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

I think it's the correct fix, although for the error display, would be better to keep the original path. Or eventually the original followed by the absolute path in parens.

@kaepr kaepr force-pushed the fix-path-ext-miss branch from b3c93f1 to e203eaa Compare March 29, 2026 06:30
- Add a test to verify symlink behavior
- Update existing tests to reflect new error message

All tests passes

```shell
TRYBUILD=overwrite RUSTUP_TOOLCHAIN=stable cargo nextest run --features full
```
@kaepr kaepr force-pushed the fix-path-ext-miss branch from e203eaa to f3c1b0d Compare March 29, 2026 06:39
@kaepr
Copy link
Copy Markdown
Contributor Author

kaepr commented Mar 29, 2026

Added changes to reflect path names for the other tests, and added a new test case to test the symlink behavior.

Comment thread testing/tests/ui/cycle.stderr Outdated
error: cyclic dependency in graph [
"\"$DIR/templates/cycle2.html/" --> \"$DIR/templates/cycle1.html/"",
"\"$DIR/templates/cycle1.html/" --> \"$DIR/templates/cycle1.html/"",
"\"$WORKSPACE/target/tests/trybuild/askama_testing/templates/cycle2.html/" --> \"$WORKSPACE/target/tests/trybuild/askama_testing/templates/cycle1.html/"",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what I meant in my comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted changes to the test files. My bad.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's the correct fix, although for the error display, would be better to keep the original path. Or eventually the original followed by the absolute path in parens.

I should be more precise. This test output will need to be updated, however we need to make it clear to the users why this cycle error occurred. What I had in mind was something like:

cyclic dependency in graph [
    "$DIR/cycle2.html" (absolute path: "$WORKSPACE/target/tests/trybuild/askama_testing/templates/cycle2.html") --> "$DIR/templates/cycle1.html/" (absolute path: "$WORKSPACE/target/tests/trybuild/askama_testing/templates/cycle1.html")
   ...
]

So the original path followed by the absolute path in parens.

Copy link
Copy Markdown
Contributor Author

@kaepr kaepr Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah got it now. It might require to keep both original and absolute path values from the find_templates's return type, or make some adjustments in the input.rs file so that the error message constructors have both the paths.

Will share the commit for this soon.

Copy link
Copy Markdown
Contributor Author

@kaepr kaepr Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have updated the error messages in the latest commit.

@kaepr kaepr force-pushed the fix-path-ext-miss branch from 01d40da to a08118c Compare March 29, 2026 15:35
Showing both paths requires storing the original path.

It needs to be threaded through to the error constructor functions.

Regenerated tests/ui files with

```shell
TRYBUILD=overwrite RUSTUP_TOOLCHAIN=stable cargo nextest run --features full
```
Comment thread askama_derive/src/input.rs Outdated
Comment thread askama_derive/src/input.rs Outdated
Comment thread askama_derive/src/input.rs Outdated
Comment thread askama_derive/src/input.rs Outdated
Comment thread askama_derive/src/input.rs Outdated
Copy link
Copy Markdown
Collaborator

@GuillaumeGomez GuillaumeGomez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the nits, looks all good!

Comment thread askama_derive/src/input.rs
Comment thread askama_derive/src/input.rs
GuillaumeGomez
GuillaumeGomez previously approved these changes Apr 1, 2026
Orig(inal) reflects usage better. Updated all usages.
@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Ah right, windows gonna be an issue (as usual).

@kaepr
Copy link
Copy Markdown
Contributor Author

kaepr commented Apr 1, 2026

Figuring that out, I am expecting running things with --target as windows should allow me to replicate it.

Given that we have changed path resolution logic itself, the solution should most likely be updating the tests cases ? Will try things locally and update.

@kaepr
Copy link
Copy Markdown
Contributor Author

kaepr commented Apr 1, 2026

It seems I can't test things locally as Windows. I only have a Mac. Tried out different ways but didn't work out.

Updated the tests to use absolute instead. This should be the fix.

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Different failure this time:

---- symlink_preserves_extension_for_escaping stdout ----

thread 'symlink_preserves_extension_for_escaping' (3008) panicked at testing\tests\paths.rs:30:5:
assertion `left == right` failed
  left: "Hello, <>&"'!\r"
 right: "Hello, <>&"'!"
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

But at least your fix for the paths display worked, well done!

kaepr added 2 commits April 1, 2026 20:17
Not having an extension is important for the testcase.
Override line endings manually. It's already done been done
for all .html and .txt files.

This should satisfy windows tests.
@kaepr kaepr force-pushed the fix-path-ext-miss branch from 2bda80a to 51d4db3 Compare April 1, 2026 14:51
@kaepr
Copy link
Copy Markdown
Contributor Author

kaepr commented Apr 1, 2026

testing/templates/symlink-target text eol=lf should satisfy windows :)

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Code looks good, CI is happy. Time to merge. Thanks a lot!

@GuillaumeGomez GuillaumeGomez merged commit 7e42946 into askama-rs:main Apr 1, 2026
50 checks passed
@kaepr
Copy link
Copy Markdown
Contributor Author

kaepr commented Apr 1, 2026

Thanks a lot for the reviews !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants