#35493: Allow `./` and `../` in paths when recursively including templates -------------------------------------+------------------------------------- Reporter: Gabriel Nick | Owner: Gabriel Pivovarov | Nick Pivovarov Type: Bug | Status: assigned Component: Template system | Version: 5.0 Severity: Normal | Resolution: Keywords: template | Triage Stage: | Unreviewed Has patch: 1 | Needs documentation: 0 Needs tests: 1 | Patch needs improvement: 0 Easy pickings: 1 | UI/UX: 0 -------------------------------------+------------------------------------- Description changed by Gabriel Nick Pivovarov:
Old description: > Hi. Currently, when trying to recursively include a Django template > within itself using the `include` tag with a path that contains `./` or > `../`, Django raises a `TemplateSyntaxError`. However, using a path that > does not contain `./` or `../` does not raise the error. When the error > is raised, the debug toolbar describes it like this: > > > = TemplateSyntaxError at / > > > > The relative path ‘“./ul.html”’ was translated to template name > ‘app/ul.html’, the same template in which the tag appears. > > Here is an example of a template in a Django app called `app` with the > path `app/templates/app/ul.html` that would produce the error given > above: > > {{{ > <ul> > {% for section in sections %} > <li> > <p>{{ section.name }}</p> > {% if section.sections|length != 0 %} > {% include "./ul.html" with sections=section.sections %} > {% endif %} > </li> > {% endfor %} > </ul> > }}} > > However, replacing the directory `./ul.html` with the equivalent > `app/ul.html` makes the error go away (assuming that the project's > `settings.py` specifies `APP_DIRS = True` and the views and URLs are > configured correctly). The actual paths are translated identically in > both cases, and the behavior of the `include` tag should not depend > simply on whether or not the path string uses `./` or `../` (or if it > should, this is not documented in the Django documentation). Therefore, > it seems that this is a bug. The expected behavior is that an error is > only raised when recursively using the `extends` template, not when > recursively using the `include` template. > > Contrapositively, it appears that recursively extending a template using > the `extends` tag with a path that does ''not'' contain `./` or `../` > raises a `TemplateDoesNotExist` exception. > > One possible fix is to modify the `django/template/loader_tags.py` file > (https://github.com/django/django/blob/main/django/template/loader_tags.py) > such that the error is raised when a template attempts to extend itself > (not when a template attempts to include itself, which would otherwise be > valid). The error handling logic in question starts on line 267 of that > file within the `construct_relative_path` function; perhaps it should > live somewhere in the `do_extends` function instead. > > Here is a relevant discussion in the Django forums: > https://forum.djangoproject.com/t/template-recursion-why-does-django-not- > allow-and/31689 New description: Hi. Currently, when trying to recursively include a Django template within itself using the `include` tag with a path that contains `./` or `../`, Django raises a `TemplateSyntaxError`. However, using a path that does not contain `./` or `../` does not raise the error. When the error is raised, the debug toolbar describes it like this: > = TemplateSyntaxError at / > > The relative path ‘“./ul.html”’ was translated to template name ‘app/ul.html’, the same template in which the tag appears. Here is an example of a template in a Django app called `app` with the path `app/templates/app/ul.html` that would produce the error given above: {{{ <ul> {% for section in sections %} <li> <p>{{ section.name }}</p> {% if section.sections|length != 0 %} {% include "./ul.html" with sections=section.sections %} {% endif %} </li> {% endfor %} </ul> }}} However, replacing the directory `./ul.html` with the equivalent `app/ul.html` makes the error go away (assuming that the project's `settings.py` specifies `APP_DIRS = True` and the views and URLs are configured correctly). The actual paths are translated identically in both cases, and the behavior of the `include` tag should not depend simply on whether or not the path string uses `./` or `../` (or if it should, this is not documented in the Django documentation). Therefore, it seems that this is a bug. The expected behavior is that an error is only raised when recursively using the `extends` template, not when recursively using the `include` template. Contrapositively, it appears that recursively extending a template using the `extends` tag with a path that does ''not'' contain `./` or `../` raises a `TemplateDoesNotExist` exception. One possible fix is to modify the `django/template/loader_tags.py` file (https://github.com/django/django/blob/main/django/template/loader_tags.py) such that the error is raised when a template attempts to extend itself (not when a template attempts to include itself, which would otherwise be valid). The error handling logic in question starts on line 267 of that file within the `construct_relative_path` function; perhaps it should only be used when called from the `do_extends` function. Here is a relevant discussion in the Django forums: https://forum.djangoproject.com/t/template-recursion-why-does-django-not- allow-and/31689 -- -- Ticket URL: <https://code.djangoproject.com/ticket/35493#comment:5> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/0107018fe67adf80-62b63331-7c16-40cc-adec-84b39214fa01-000000%40eu-central-1.amazonses.com.