#35493: Allow `./` and `../` in paths when recursively including templates
-------------------------------------+-------------------------------------
     Reporter:  Gabriel Nick         |                    Owner:  nobody
  Pivovarov                          |
         Type:  Bug                  |                   Status:  new
    Component:  Template system      |                  Version:  5.0
     Severity:  Normal               |               Resolution:
     Keywords:  template             |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  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, which is semantically
> inaccurate since the template is referencing itself and therefore
> necessarily exists.
>
> 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 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

--
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35493#comment:1>
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018fe492695b-d14ab244-0d93-42b1-bce6-debea0c6ab13-000000%40eu-central-1.amazonses.com.

Reply via email to