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 | """ |