From nobody Mon Sep 17 00:00:00 2001
From: Michael Radziej <mir@noris.de>
Date: Tue Feb 6 12:56:20 2007 +0100
Subject: [PATCH] autoescape 2

Refreshed patch autoescape-2.
(Base: 560bc8fabc50d97ea48f2a8034a8e2a01d004fa6)
(Last: b63fc517f24a697640c5b815bb1f4a70751d9f8a)

---

 django/contrib/csrf/middleware.py                |    7 +++--
 django/contrib/humanize/templatetags/humanize.py |    4 +++
 django/contrib/markup/templatetags/markup.py     |   16 ++++++----
 django/views/debug.py                            |   34 ++++++++++++----------
 4 files changed, 37 insertions(+), 24 deletions(-)

base e2bddd7b0de6f643f7702089680ca1c38494f5c7
last fd6b16b326b63c6db185a104d1b4e99e0ab63409
diff --git a/django/contrib/csrf/middleware.py b/django/contrib/csrf/middleware.py
index 93a9484ca655ef96032871ca1a6c5444c11daef2..15ff69a088b27edab7830edb1e833901edc45d87 100644
--- a/django/contrib/csrf/middleware.py
+++ b/django/contrib/csrf/middleware.py
@@ -7,11 +7,12 @@ against request forgeries from other sit
 """
 from django.conf import settings
 from django.http import HttpResponseForbidden
+from django.utils.safestring import mark_safe
 import md5
 import re
 import itertools
 
-_ERROR_MSG = '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>'
+_ERROR_MSG = mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>')
 
 _POST_FORM_RE = \
     re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)
@@ -82,10 +83,10 @@ class CsrfMiddleware(object):
                                             itertools.repeat(''))
             def add_csrf_field(match):
                 """Returns the matched <form> tag plus the added <input> element"""
-                return match.group() + "<div style='display:none;'>" + \
+                return mark_safe(match.group() + "<div style='display:none;'>" + \
                 "<input type='hidden' " + idattributes.next() + \
                 " name='csrfmiddlewaretoken' value='" + csrf_token + \
-                "' /></div>"
+                "' /></div>")
 
             # Modify any POST forms
             response.content = _POST_FORM_RE.sub(add_csrf_field, response.content)
diff --git a/django/contrib/humanize/templatetags/humanize.py b/django/contrib/humanize/templatetags/humanize.py
index b2d28a0ab4f86a49de2cea8c3dda94c870d1c32a..b2d368bc5716569db37ae169e1f083669fd3f8b1 100644
--- a/django/contrib/humanize/templatetags/humanize.py
+++ b/django/contrib/humanize/templatetags/humanize.py
@@ -16,6 +16,7 @@ def ordinal(value):
     if value % 100 in (11, 12, 13): # special case
         return '%dth' % value
     return '%d%s' % (value, t[value % 10])
+ordinal.is_safe = True
 register.filter(ordinal)
 
 def intcomma(value):
@@ -29,6 +30,7 @@ def intcomma(value):
         return new
     else:
         return intcomma(new)
+intcomma.is_safe = True
 register.filter(intcomma)
 
 def intword(value):
@@ -47,6 +49,7 @@ def intword(value):
     if value < 1000000000000000:
         return '%.1f trillion' % (value / 1000000000000.0)
     return value
+intword.is_safe = False
 register.filter(intword)
 
 def apnumber(value):
@@ -61,4 +64,5 @@ def apnumber(value):
     if not 0 < value < 10:
         return value
     return ('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine')[value-1]
+apnumber.is_safe = True
 register.filter(apnumber)
diff --git a/django/contrib/markup/templatetags/markup.py b/django/contrib/markup/templatetags/markup.py
index 4bb135cc32e3937102abd1e6ca62baffd65e1ee9..a8a09cec9e7481a6760f7c55841d9ffacd2e1a2d 100644
--- a/django/contrib/markup/templatetags/markup.py
+++ b/django/contrib/markup/templatetags/markup.py
@@ -16,6 +16,7 @@ silently fail and return the un-marked-u
 
 from django import template
 from django.conf import settings
+from django.utils.safestring import mark_safe
 
 register = template.Library()
 
@@ -25,9 +26,10 @@ def textile(value):
     except ImportError:
         if settings.DEBUG:
             raise template.TemplateSyntaxError, "Error in {% textile %} filter: The Python textile library isn't installed."
-        return value
+        return mark_safe(value)
     else:
-        return textile.textile(value, encoding=settings.DEFAULT_CHARSET, output=settings.DEFAULT_CHARSET)
+        return mark_safe(textile.textile(value, encoding=settings.DEFAULT_CHARSET, output=settings.DEFAULT_CHARSET))
+textile.is_safe = True
 
 def markdown(value):
     try:
@@ -35,9 +37,10 @@ def markdown(value):
     except ImportError:
         if settings.DEBUG:
             raise template.TemplateSyntaxError, "Error in {% markdown %} filter: The Python markdown library isn't installed."
-        return value
+        return mark_safe(value)
     else:
-        return markdown.markdown(value)
+        return mark_safe(markdown.markdown(value))
+markdown.is_safe = True
 
 def restructuredtext(value):
     try:
@@ -45,11 +48,12 @@ def restructuredtext(value):
     except ImportError:
         if settings.DEBUG:
             raise template.TemplateSyntaxError, "Error in {% restructuredtext %} filter: The Python docutils library isn't installed."
-        return value
+        return mark_safe(value)
     else:
         docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
         parts = publish_parts(source=value, writer_name="html4css1", settings_overrides=docutils_settings)
-        return parts["fragment"]
+        return mark_safe(parts["fragment"])
+restructuredtext.is_safe = True
 
 register.filter(textile)
 register.filter(markdown)
diff --git a/django/views/debug.py b/django/views/debug.py
index 77b6c2fac2caa9e554fadbb61cfdd8b955948c63..31215429022e41905618d02034daf14674bb3893 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -290,7 +290,7 @@ TECHNICAL_500_TEMPLATE = """
   </script>
 </head>
 <body>
-
+{% autoescape %}
 <div id="summary">
   <h1>{{ exception_type }} at {{ request.path|escape }}</h1>
   <h2>{{ exception_value|escape }}</h2>
@@ -338,7 +338,7 @@ TECHNICAL_500_TEMPLATE = """
 <div id="template">
    <h2>Template error</h2>
    <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
-   <h3>{{ template_info.message|escape }}</h3>
+   <h3>{{ template_info.message }}</h3>
    <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}">
    {% for source_line in template_info.source_lines %}
    {% ifequal source_line.0 template_info.line %}
@@ -365,11 +365,11 @@ TECHNICAL_500_TEMPLATE = """
           {% if frame.context_line %}
             <div class="context" id="c{{ frame.id }}">
               {% if frame.pre_context %}
-                <ol start="{{ frame.pre_context_lineno }}" class="pre-context" id="pre{{ frame.id }}">{% for line in frame.pre_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endfor %}</ol>
+                <ol start="{{ frame.pre_context_lineno }}" class="pre-context" id="pre{{ frame.id }}">{% for line in frame.pre_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line }}</li>{% endfor %}</ol>
               {% endif %}
-              <ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line|escape }} <span>...</span></li></ol>
+              <ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line }} <span>...</span></li></ol>
               {% if frame.post_context %}
-                <ol start='{{ frame.lineno|add:"1" }}' class="post-context" id="post{{ frame.id }}">{% for line in frame.post_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endfor %}</ol>
+                <ol start='{{ frame.lineno|add:"1" }}' class="post-context" id="post{{ frame.id }}">{% for line in frame.post_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line }}</li>{% endfor %}</ol>
               {% endif %}
             </div>
           {% endif %}
@@ -389,7 +389,7 @@ TECHNICAL_500_TEMPLATE = """
                 {% for var in frame.vars|dictsort:"0" %}
                   <tr>
                     <td>{{ var.0 }}</td>
-                    <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
+                    <td class="code"><div>{{ var.1|pprint }}</div></td>
                   </tr>
                 {% endfor %}
               </tbody>
@@ -409,7 +409,7 @@ Traceback (most recent call last):<br/>
 {% for frame in frames %}
   File "{{ frame.filename }}" in {{ frame.function }}<br/>
   {% if frame.context_line %}
-    &nbsp;&nbsp;{{ frame.lineno }}. {{ frame.context_line|escape }}<br/>
+    &nbsp;&nbsp;{{ frame.lineno }}. {{ frame.context_line }}<br/>
   {% endif %}
 {% endfor %}<br/>
 &nbsp;&nbsp;{{ exception_type }} at {{ request.path|escape }}<br/>
@@ -437,7 +437,7 @@ Traceback (most recent call last):<br/>
         {% for var in request.GET.items %}
           <tr>
             <td>{{ var.0 }}</td>
-            <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
+            <td class="code"><div>{{ var.1|pprint }}</div></td>
           </tr>
         {% endfor %}
       </tbody>
@@ -459,7 +459,7 @@ Traceback (most recent call last):<br/>
         {% for var in request.POST.items %}
           <tr>
             <td>{{ var.0 }}</td>
-            <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
+            <td class="code"><div>{{ var.1|pprint }}</div></td>
           </tr>
         {% endfor %}
       </tbody>
@@ -481,7 +481,7 @@ Traceback (most recent call last):<br/>
         {% for var in request.COOKIES.items %}
           <tr>
             <td>{{ var.0 }}</td>
-            <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
+            <td class="code"><div>{{ var.1|pprint }}</div></td>
           </tr>
         {% endfor %}
       </tbody>
@@ -502,7 +502,7 @@ Traceback (most recent call last):<br/>
       {% for var in request.META.items|dictsort:"0" %}
         <tr>
           <td>{{ var.0 }}</td>
-          <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
+          <td class="code"><div>{{ var.1|pprint }}</div></td>
         </tr>
       {% endfor %}
     </tbody>
@@ -521,7 +521,7 @@ Traceback (most recent call last):<br/>
       {% for var in settings.items|dictsort:"0" %}
         <tr>
           <td>{{ var.0 }}</td>
-          <td class="code"><div>{{ var.1|pprint|escape }}</div></td>
+          <td class="code"><div>{{ var.1|pprint }}</div></td>
         </tr>
       {% endfor %}
     </tbody>
@@ -536,7 +536,7 @@ Traceback (most recent call last):<br/>
     display a standard 500 page.
   </p>
 </div>
-
+{% endautoescape %}
 </body>
 </html>
 """
@@ -567,6 +567,7 @@ TECHNICAL_404_TEMPLATE = """
   </style>
 </head>
 <body>
+{% autoescape %}
   <div id="summary">
     <h1>Page not found <span>(404)</span></h1>
     <table class="meta">
@@ -588,12 +589,12 @@ TECHNICAL_404_TEMPLATE = """
       </p>
       <ol>
         {% for pattern in urlpatterns %}
-          <li>{{ pattern|escape }}</li>
+          <li>{{ pattern }}</li>
         {% endfor %}
       </ol>
       <p>The current URL, <code>{{ request.path|escape }}</code>, didn't match any of these.</p>
     {% else %}
-      <p>{{ reason|escape }}</p>
+      <p>{{ reason }}</p>
     {% endif %}
   </div>
 
@@ -604,6 +605,7 @@ TECHNICAL_404_TEMPLATE = """
       will display a standard 404 page.
     </p>
   </div>
+{% endautoescape %}
 </body>
 </html>
 """
@@ -638,6 +640,7 @@ EMPTY_URLCONF_TEMPLATE = """
 </head>
 
 <body>
+{% autoescape %}
 <div id="summary">
   <h1>It worked!</h1>
   <h2>Congratulations on your first Django-powered page.</h2>
@@ -657,5 +660,6 @@ EMPTY_URLCONF_TEMPLATE = """
     Django settings file and you haven't configured any URLs. Get to work!
   </p>
 </div>
+{% endautoescape %}
 </body></html>
 """
-- 
1.4.GIT-dirty

