Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build hangs due to unintended template recursion #515

Closed
Rapptz opened this issue Jul 13, 2021 · 6 comments
Closed

Build hangs due to unintended template recursion #515

Rapptz opened this issue Jul 13, 2021 · 6 comments

Comments

@Rapptz
Copy link

Rapptz commented Jul 13, 2021

Apologies for the title, I wasn't sure how to properly phrase this.

While working on my project I ran into a scenario where rustc would hang indefinitely for some reason. After a laborious amount of time trying to debug and figure out the issue to produce a minimal example, it turned out that template searching does not work as I expect. For example, suppose the following directory structure was used:

templates/
  admin/
    index.html
  base.html
  index.html

If admin/index.html has {% extends "base.html" %} then the file that is included is the one given by templates/base.html. Therefore, my expectation was that the lookup is based off of the root directory and not the relative directory. However, once the directory is modified and templates/admin/base.html is created like so:

templates/
  admin/
    base.html
    index.html
  base.html
  index.html

Then running {% extends "base.html" %} from within templates/admin/base.html does not look for templates/index.html like before but instead it seems to recursively include itself causing the build to hang.

I am unsure if this is by design, a user issue, or a bug within Askama. However, I figured there's no harm in documenting it here.

I have included a zip file of a minimal project layout demonstrating the hang

askama-bug.zip

@djc
Copy link
Owner

djc commented Jul 13, 2021

The lookup itself is by design. We should probably try to abort once we notice we're in a loop, though. Would you be interested in submitting a PR for that? This kind of thing probably happens around here: https://github.com/djc/askama/blob/main/askama_derive/src/lib.rs#L50, or inside the Heritage::new() call.

@grv07
Copy link
Contributor

grv07 commented Oct 5, 2021

What about the case of the cycle in dependency ?
if a.html --- extends ---> b.html --extends ---> c.html ---extends---> a.html

@djc
Copy link
Owner

djc commented Oct 6, 2021

What about it? Please be more explicit in what you're asking about.

@grv07
Copy link
Contributor

grv07 commented Oct 6, 2021

My apologies for that, the last comment suppose to be edited.

As @Rapptz explains there is an issue of self-loop when base.html tries to extend itself and leads to an infinite loop.
My solution is to detect this loop at https://github.com/djc/askama/blob/main/askama_derive/src/lib.rs#L84 by check if the source path and extends are equal then raise CompileError("There is a cyclic dependency between {path} and {extends}").

This solution will solve the self-loop problem, but it will not work for the condition where extends leads to circular dependency that also hangs the build.
if a.html --- extends ---> b.html --extends ---> c.html ---extends---> a.html

So, to solve both of the cases should we use a graph(build based on source paths) to detect the cycle and raise the CompileError if there is any cycle found?

@djc
Copy link
Owner

djc commented Oct 6, 2021

I think the Heritage already contains such a graph. If you can use that to also block indirect cyclic dependencies, that would be great.

@grv07
Copy link
Contributor

grv07 commented Oct 28, 2021

This got resolved with #539 .
Please check :)

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

No branches or pull requests

3 participants