Code

Ticket #9666: 9666-with-tests.diff

File 9666-with-tests.diff, 5.6 KB (added by ericholscher, 5 years ago)

Actually attach template this time.

Line 
1diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
2index 835b1a9..91bc169 100644
3--- a/django/template/defaulttags.py
4+++ b/django/template/defaulttags.py
5@@ -2,6 +2,7 @@
6 
7 import sys
8 import re
9+import os
10 from itertools import cycle as itertools_cycle
11 try:
12     reversed
13@@ -287,20 +288,25 @@ class SsiNode(Node):
14         self.filepath, self.parsed = filepath, parsed
15 
16     def render(self, context):
17-        if not include_is_allowed(self.filepath):
18+        filepath = self.filepath
19+        try:
20+            filepath = filepath.resolve(context)
21+        except (AttributeError, VariableDoesNotExist):
22+            pass
23+        if not include_is_allowed(filepath):
24             if settings.DEBUG:
25                 return "[Didn't have permission to include file]"
26             else:
27                 return '' # Fail silently for invalid includes.
28         try:
29-            fp = open(self.filepath, 'r')
30+            fp = open(filepath, 'r')
31             output = fp.read()
32             fp.close()
33         except IOError:
34             output = ''
35         if self.parsed:
36             try:
37-                t = Template(output, name=self.filepath)
38+                t = Template(output, name=filepath)
39                 return t.render(context)
40             except TemplateSyntaxError, e:
41                 if settings.DEBUG:
42@@ -377,7 +383,7 @@ class URLNode(Node):
43                 except NoReverseMatch:
44                     if self.asvar is None:
45                         # Re-raise the original exception, not the one with
46-                        # the path relative to the project. This makes a
47+                        # the path relative to the project. This makes a
48                         # better error message.
49                         raise e
50             else:
51@@ -897,7 +903,12 @@ def ssi(parser, token):
52         else:
53             raise TemplateSyntaxError("Second (optional) argument to %s tag"
54                                       " must be 'parsed'" % bits[0])
55-    return SsiNode(bits[1], parsed)
56+    var = bits[1]
57+    #For backwards compatibility, let things that look like a path be quoted.
58+    if os.path.sep in var and var[0] != "'" and var[0] != '"':
59+        var = '"' + var + '"'
60+    var = parser.compile_filter(var)
61+    return SsiNode(var, parsed)
62 ssi = register.tag(ssi)
63 
64 #@register.tag
65diff --git a/tests/regressiontests/templates/ssi_include.html b/tests/regressiontests/templates/ssi_include.html
66new file mode 100755
67index 0000000..58d5926
68--- /dev/null
69+++ b/tests/regressiontests/templates/ssi_include.html
70@@ -0,0 +1 @@
71+This is for testing an ssi include. {{ test }}
72diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
73index 953e8fa..6767778 100644
74--- a/tests/regressiontests/templates/tests.py
75+++ b/tests/regressiontests/templates/tests.py
76@@ -69,7 +69,7 @@ class SomeException(Exception):
77 
78 class SomeOtherException(Exception):
79     pass
80-   
81+
82 class ContextStackException(Exception):
83     pass
84 
85@@ -211,6 +211,9 @@ class Templates(unittest.TestCase):
86         old_invalid = settings.TEMPLATE_STRING_IF_INVALID
87         expected_invalid_str = 'INVALID'
88 
89+        #Set ALLOWED_INCLUDE_ROOTS so that ssi works.
90+        old_allowed, settings.ALLOWED_INCLUDE_ROOTS = settings.ALLOWED_INCLUDE_ROOTS, os.path.dirname(os.path.abspath(__file__))
91+
92         for name, vals in tests:
93             if isinstance(vals[2], tuple):
94                 normal_string_result = vals[2][0]
95@@ -257,6 +260,7 @@ class Templates(unittest.TestCase):
96         deactivate()
97         settings.TEMPLATE_DEBUG = old_td
98         settings.TEMPLATE_STRING_IF_INVALID = old_invalid
99+        settings.ALLOWED_INCLUDE_ROOTS = old_allowed
100 
101         self.assertEqual(failures, [], "Tests failed:\n%s\n%s" %
102             ('-'*70, ("\n%s\n" % ('-'*70)).join(failures)))
103@@ -915,6 +919,20 @@ class Templates(unittest.TestCase):
104                           '{% endfor %}',
105                           {}, ''),
106 
107+            ### SSI TAG ########################################################
108+            #Test normal behavior
109+            'ssi01': ('{%% ssi %s %%}' % os.path.join(os.path.dirname(os.path.abspath(__file__)), 'ssi_include.html'), {}, 'This is for testing an ssi include. {{ test }}\n'),
110+            'ssi02': ('{%% ssi %s %%}' % os.path.join(os.path.dirname(os.path.abspath(__file__)), 'not_here'), {}, ''),
111+            #Test passing as a variable
112+            'ssi03': ('{% ssi ssi_file %}', {'ssi_file': os.path.join(os.path.dirname(os.path.abspath(__file__)), 'ssi_include.html')}, 'This is for testing an ssi include. {{ test }}\n'),
113+            'ssi04': ('{% ssi ssi_file %}', {'ssi_file': 'no_file'}, ''),
114+            #Test parsed output
115+            'ssi05': ('{%% ssi %s parsed %%}' % os.path.join(os.path.dirname(os.path.abspath(__file__)), 'ssi_include.html'), {'test': 'Look ma! It parsed!'}, 'This is for testing an ssi include. Look ma! It parsed!\n'),
116+            'ssi06': ('{%% ssi %s parsed %%}' % os.path.join(os.path.dirname(os.path.abspath(__file__)), 'not_here'), {'test': 'Look ma! It parsed!'}, ''),
117+            #Test quoting
118+            'ssi07': ('{%% ssi "%s" %%}' % os.path.join(os.path.dirname(os.path.abspath(__file__)), 'ssi_include.html'), {}, 'This is for testing an ssi include. {{ test }}\n'),
119+            'ssi08': ('{%% ssi "%s" %%}' % os.path.join(os.path.dirname(os.path.abspath(__file__)), 'not_here'), {}, ''),
120+
121             ### TEMPLATETAG TAG #######################################################
122             'templatetag01': ('{% templatetag openblock %}', {}, '{%'),
123             'templatetag02': ('{% templatetag closeblock %}', {}, '%}'),