From nobody Mon Sep 17 00:00:00 2001
From: Michael Radziej <mir@noris.de>
Date: Wed Jul 18 11:26:33 2007 +0200
Subject: [PATCH] autoescape 2
Refreshed patch autoescape-2.
(Base: 147ff090a7d3d71a6e4ccf91e737f2ae7d108350)
(Last: 1021397be7f57b6e45261863533df69f4f8e9aea)
---
django/contrib/csrf/middleware.py | 7 +++--
django/contrib/humanize/templatetags/humanize.py | 4 +++
django/contrib/markup/templatetags/markup.py | 10 +++++-
django/views/debug.py | 34 ++++++++++++----------
4 files changed, 34 insertions(+), 21 deletions(-)
base 35e6d247f711b3224d045c1f8668ed5d3302950c
last 419816ceedba19a677c9c902359f164f1f4e08da
diff --git a/django/contrib/csrf/middleware.py b/django/contrib/csrf/middleware.py
index 93a9484ca655ef96032871ca1a6c5444c11daef2..15ff69a088b27edab7830edb1e833901edc45d87 100644
|
a
|
b
|
against request forgeries from other sites.
|
| 7 | 7 | """ |
| 8 | 8 | from django.conf import settings |
| 9 | 9 | from django.http import HttpResponseForbidden |
| | 10 | from django.utils.safestring import mark_safe |
| 10 | 11 | import md5 |
| 11 | 12 | import re |
| 12 | 13 | import itertools |
| 13 | 14 | |
| 14 | | _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>' |
| | 15 | _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>') |
| 15 | 16 | |
| 16 | 17 | _POST_FORM_RE = \ |
| 17 | 18 | re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE) |
| … |
… |
class CsrfMiddleware(object):
|
| 82 | 83 | itertools.repeat('')) |
| 83 | 84 | def add_csrf_field(match): |
| 84 | 85 | """Returns the matched <form> tag plus the added <input> element""" |
| 85 | | return match.group() + "<div style='display:none;'>" + \ |
| | 86 | return mark_safe(match.group() + "<div style='display:none;'>" + \ |
| 86 | 87 | "<input type='hidden' " + idattributes.next() + \ |
| 87 | 88 | " name='csrfmiddlewaretoken' value='" + csrf_token + \ |
| 88 | | "' /></div>" |
| | 89 | "' /></div>") |
| 89 | 90 | |
| 90 | 91 | # Modify any POST forms |
| 91 | 92 | 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 699d9300b8ea478e82ec21da8913ecea4eaaf40b..c391ef2b3bb3ef1bd9d99c086b4bfb277cfce8fe 100644
|
a
|
b
|
def ordinal(value):
|
| 18 | 18 | if value % 100 in (11, 12, 13): # special case |
| 19 | 19 | return u"%d%s" % (value, t[0]) |
| 20 | 20 | return u'%d%s' % (value, t[value % 10]) |
| | 21 | ordinal.is_safe = True |
| 21 | 22 | register.filter(ordinal) |
| 22 | 23 | |
| 23 | 24 | def intcomma(value): |
| … |
… |
def intcomma(value):
|
| 31 | 32 | return new |
| 32 | 33 | else: |
| 33 | 34 | return intcomma(new) |
| | 35 | intcomma.is_safe = True |
| 34 | 36 | register.filter(intcomma) |
| 35 | 37 | |
| 36 | 38 | def intword(value): |
| … |
… |
def intword(value):
|
| 52 | 54 | new_value = value / 1000000000000.0 |
| 53 | 55 | return ungettext('%(value).1f trillion', '%(value).1f trillion', new_value) % {'value': new_value} |
| 54 | 56 | return value |
| | 57 | intword.is_safe = False |
| 55 | 58 | register.filter(intword) |
| 56 | 59 | |
| 57 | 60 | def apnumber(value): |
| … |
… |
def apnumber(value):
|
| 66 | 69 | if not 0 < value < 10: |
| 67 | 70 | return value |
| 68 | 71 | return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1] |
| | 72 | apnumber.is_safe = True |
| 69 | 73 | register.filter(apnumber) |
diff --git a/django/contrib/markup/templatetags/markup.py b/django/contrib/markup/templatetags/markup.py
index 5d1f0ff1fb26564702822e57dc56f01970ae32b6..13708fd26df27cec10c45672f9cb9a6f15e7caf1 100644
|
a
|
b
|
silently fail and return the un-marked-up text.
|
| 17 | 17 | from django import template |
| 18 | 18 | from django.conf import settings |
| 19 | 19 | from django.utils.encoding import smart_str, force_unicode |
| | 20 | from django.utils.safestring import mark_safe |
| 20 | 21 | |
| 21 | 22 | register = template.Library() |
| 22 | 23 | |
| … |
… |
def textile(value):
|
| 28 | 29 | raise template.TemplateSyntaxError, "Error in {% textile %} filter: The Python textile library isn't installed." |
| 29 | 30 | return force_unicode(value) |
| 30 | 31 | else: |
| 31 | | return force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8')) |
| | 32 | return mark_safe(force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8'))) |
| | 33 | textile.is_safe = True |
| 32 | 34 | |
| 33 | 35 | def markdown(value): |
| 34 | 36 | try: |
| … |
… |
def markdown(value):
|
| 38 | 40 | raise template.TemplateSyntaxError, "Error in {% markdown %} filter: The Python markdown library isn't installed." |
| 39 | 41 | return force_unicode(value) |
| 40 | 42 | else: |
| 41 | | return force_unicode(markdown.markdown(smart_str(value))) |
| | 43 | return mark_safe(force_unicode(markdown.markdown(smart_str(value)))) |
| | 44 | markdown.is_safe = True |
| 42 | 45 | |
| 43 | 46 | def restructuredtext(value): |
| 44 | 47 | try: |
| … |
… |
def restructuredtext(value):
|
| 50 | 53 | else: |
| 51 | 54 | docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {}) |
| 52 | 55 | parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings) |
| 53 | | return force_unicode(parts["fragment"]) |
| | 56 | return mark_safe(force_unicode(parts["fragment"])) |
| | 57 | restructuredtext.is_safe = True |
| 54 | 58 | |
| 55 | 59 | register.filter(textile) |
| 56 | 60 | register.filter(markdown) |
diff --git a/django/views/debug.py b/django/views/debug.py
index d2efe76072dd40a62efaf563d150ba0be0149ab6..ccf02c007aa39647555613089808151bd43eb95d 100644
|
a
|
b
|
TECHNICAL_500_TEMPLATE = """
|
| 323 | 323 | </script> |
| 324 | 324 | </head> |
| 325 | 325 | <body> |
| 326 | | |
| | 326 | {% autoescape %} |
| 327 | 327 | <div id="summary"> |
| 328 | 328 | <h1>{{ exception_type }} at {{ request.path|escape }}</h1> |
| 329 | 329 | <h2>{{ exception_value|escape }}</h2> |
| … |
… |
TECHNICAL_500_TEMPLATE = """
|
| 379 | 379 | <div id="template"> |
| 380 | 380 | <h2>Template error</h2> |
| 381 | 381 | <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p> |
| 382 | | <h3>{{ template_info.message|escape }}</h3> |
| | 382 | <h3>{{ template_info.message }}</h3> |
| 383 | 383 | <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}"> |
| 384 | 384 | {% for source_line in template_info.source_lines %} |
| 385 | 385 | {% ifequal source_line.0 template_info.line %} |
| … |
… |
TECHNICAL_500_TEMPLATE = """
|
| 406 | 406 | {% if frame.context_line %} |
| 407 | 407 | <div class="context" id="c{{ frame.id }}"> |
| 408 | 408 | {% if frame.pre_context %} |
| 409 | | <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> |
| | 409 | <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> |
| 410 | 410 | {% endif %} |
| 411 | | <ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line|escape }} <span>...</span></li></ol> |
| | 411 | <ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line }} <span>...</span></li></ol> |
| 412 | 412 | {% if frame.post_context %} |
| 413 | | <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> |
| | 413 | <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> |
| 414 | 414 | {% endif %} |
| 415 | 415 | </div> |
| 416 | 416 | {% endif %} |
| … |
… |
TECHNICAL_500_TEMPLATE = """
|
| 430 | 430 | {% for var in frame.vars|dictsort:"0" %} |
| 431 | 431 | <tr> |
| 432 | 432 | <td>{{ var.0 }}</td> |
| 433 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| | 433 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
| 434 | 434 | </tr> |
| 435 | 435 | {% endfor %} |
| 436 | 436 | </tbody> |
| … |
… |
Traceback (most recent call last):<br/>
|
| 450 | 450 | {% for frame in frames %} |
| 451 | 451 | File "{{ frame.filename }}" in {{ frame.function }}<br/> |
| 452 | 452 | {% if frame.context_line %} |
| 453 | | {{ frame.lineno }}. {{ frame.context_line|escape }}<br/> |
| | 453 | {{ frame.lineno }}. {{ frame.context_line }}<br/> |
| 454 | 454 | {% endif %} |
| 455 | 455 | {% endfor %}<br/> |
| 456 | 456 | {{ exception_type }} at {{ request.path|escape }}<br/> |
| … |
… |
Traceback (most recent call last):<br/>
|
| 478 | 478 | {% for var in request.GET.items %} |
| 479 | 479 | <tr> |
| 480 | 480 | <td>{{ var.0 }}</td> |
| 481 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| | 481 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
| 482 | 482 | </tr> |
| 483 | 483 | {% endfor %} |
| 484 | 484 | </tbody> |
| … |
… |
Traceback (most recent call last):<br/>
|
| 500 | 500 | {% for var in request.POST.items %} |
| 501 | 501 | <tr> |
| 502 | 502 | <td>{{ var.0 }}</td> |
| 503 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| | 503 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
| 504 | 504 | </tr> |
| 505 | 505 | {% endfor %} |
| 506 | 506 | </tbody> |
| … |
… |
Traceback (most recent call last):<br/>
|
| 522 | 522 | {% for var in request.COOKIES.items %} |
| 523 | 523 | <tr> |
| 524 | 524 | <td>{{ var.0 }}</td> |
| 525 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| | 525 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
| 526 | 526 | </tr> |
| 527 | 527 | {% endfor %} |
| 528 | 528 | </tbody> |
| … |
… |
Traceback (most recent call last):<br/>
|
| 543 | 543 | {% for var in request.META.items|dictsort:"0" %} |
| 544 | 544 | <tr> |
| 545 | 545 | <td>{{ var.0 }}</td> |
| 546 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| | 546 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
| 547 | 547 | </tr> |
| 548 | 548 | {% endfor %} |
| 549 | 549 | </tbody> |
| … |
… |
Traceback (most recent call last):<br/>
|
| 562 | 562 | {% for var in settings.items|dictsort:"0" %} |
| 563 | 563 | <tr> |
| 564 | 564 | <td>{{ var.0 }}</td> |
| 565 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| | 565 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
| 566 | 566 | </tr> |
| 567 | 567 | {% endfor %} |
| 568 | 568 | </tbody> |
| … |
… |
Traceback (most recent call last):<br/>
|
| 577 | 577 | display a standard 500 page. |
| 578 | 578 | </p> |
| 579 | 579 | </div> |
| 580 | | |
| | 580 | {% endautoescape %} |
| 581 | 581 | </body> |
| 582 | 582 | </html> |
| 583 | 583 | """ |
| … |
… |
TECHNICAL_404_TEMPLATE = """
|
| 608 | 608 | </style> |
| 609 | 609 | </head> |
| 610 | 610 | <body> |
| | 611 | {% autoescape %} |
| 611 | 612 | <div id="summary"> |
| 612 | 613 | <h1>Page not found <span>(404)</span></h1> |
| 613 | 614 | <table class="meta"> |
| … |
… |
TECHNICAL_404_TEMPLATE = """
|
| 629 | 630 | </p> |
| 630 | 631 | <ol> |
| 631 | 632 | {% for pattern in urlpatterns %} |
| 632 | | <li>{{ pattern|escape }}</li> |
| | 633 | <li>{{ pattern }}</li> |
| 633 | 634 | {% endfor %} |
| 634 | 635 | </ol> |
| 635 | 636 | <p>The current URL, <code>{{ request_path|escape }}</code>, didn't match any of these.</p> |
| 636 | 637 | {% else %} |
| 637 | | <p>{{ reason|escape }}</p> |
| | 638 | <p>{{ reason }}</p> |
| 638 | 639 | {% endif %} |
| 639 | 640 | </div> |
| 640 | 641 | |
| … |
… |
TECHNICAL_404_TEMPLATE = """
|
| 645 | 646 | will display a standard 404 page. |
| 646 | 647 | </p> |
| 647 | 648 | </div> |
| | 649 | {% endautoescape %} |
| 648 | 650 | </body> |
| 649 | 651 | </html> |
| 650 | 652 | """ |
| … |
… |
EMPTY_URLCONF_TEMPLATE = """
|
| 679 | 681 | </head> |
| 680 | 682 | |
| 681 | 683 | <body> |
| | 684 | {% autoescape %} |
| 682 | 685 | <div id="summary"> |
| 683 | 686 | <h1>It worked!</h1> |
| 684 | 687 | <h2>Congratulations on your first Django-powered page.</h2> |
| … |
… |
EMPTY_URLCONF_TEMPLATE = """
|
| 698 | 701 | Django settings file and you haven't configured any URLs. Get to work! |
| 699 | 702 | </p> |
| 700 | 703 | </div> |
| | 704 | {% endautoescape %} |
| 701 | 705 | </body></html> |
| 702 | 706 | """ |