#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.

Reply via email to