From nobody Mon Sep 17 00:00:00 2001
From: Michael Radziej <mir@noris.de>
Date: Fri Mar 2 11:54:31 2007 +0100
Subject: [PATCH] autoescape 2
Integrated templatetages/markup part of smurf's patch
---
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 a92825872b39cf5a4592d222885a3251b7129a27
last 3746d911627126ccb340a5fbbe3b6fb63106088b
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 sit
|
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 b2d28a0ab4f86a49de2cea8c3dda94c870d1c32a..b2d368bc5716569db37ae169e1f083669fd3f8b1 100644
a
|
b
|
def ordinal(value):
|
16 | 16 | if value % 100 in (11, 12, 13): # special case |
17 | 17 | return '%dth' % value |
18 | 18 | return '%d%s' % (value, t[value % 10]) |
| 19 | ordinal.is_safe = True |
19 | 20 | register.filter(ordinal) |
20 | 21 | |
21 | 22 | def intcomma(value): |
… |
… |
def intcomma(value):
|
29 | 30 | return new |
30 | 31 | else: |
31 | 32 | return intcomma(new) |
| 33 | intcomma.is_safe = True |
32 | 34 | register.filter(intcomma) |
33 | 35 | |
34 | 36 | def intword(value): |
… |
… |
def intword(value):
|
47 | 49 | if value < 1000000000000000: |
48 | 50 | return '%.1f trillion' % (value / 1000000000000.0) |
49 | 51 | return value |
| 52 | intword.is_safe = False |
50 | 53 | register.filter(intword) |
51 | 54 | |
52 | 55 | def apnumber(value): |
… |
… |
def apnumber(value):
|
61 | 64 | if not 0 < value < 10: |
62 | 65 | return value |
63 | 66 | return ('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine')[value-1] |
| 67 | apnumber.is_safe = True |
64 | 68 | register.filter(apnumber) |
diff --git a/django/contrib/markup/templatetags/markup.py b/django/contrib/markup/templatetags/markup.py
index 4bb135cc32e3937102abd1e6ca62baffd65e1ee9..df8dfd1ef969007189fa394434859ff765633118 100644
a
|
b
|
silently fail and return the un-marked-u
|
16 | 16 | |
17 | 17 | from django import template |
18 | 18 | from django.conf import settings |
| 19 | from django.utils.safestring import mark_safe |
19 | 20 | |
20 | 21 | register = template.Library() |
21 | 22 | |
… |
… |
def textile(value):
|
27 | 28 | raise template.TemplateSyntaxError, "Error in {% textile %} filter: The Python textile library isn't installed." |
28 | 29 | return value |
29 | 30 | else: |
30 | | return textile.textile(value, encoding=settings.DEFAULT_CHARSET, output=settings.DEFAULT_CHARSET) |
| 31 | return mark_safe(textile.textile(value, encoding=settings.DEFAULT_CHARSET, output=settings.DEFAULT_CHARSET)) |
| 32 | textile.is_safe = True |
31 | 33 | |
32 | 34 | def markdown(value): |
33 | 35 | try: |
… |
… |
def markdown(value):
|
37 | 39 | raise template.TemplateSyntaxError, "Error in {% markdown %} filter: The Python markdown library isn't installed." |
38 | 40 | return value |
39 | 41 | else: |
40 | | return markdown.markdown(value) |
| 42 | return mark_safe(markdown.markdown(value)) |
| 43 | markdown.is_safe = True |
41 | 44 | |
42 | 45 | def restructuredtext(value): |
43 | 46 | try: |
… |
… |
def restructuredtext(value):
|
49 | 52 | else: |
50 | 53 | docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {}) |
51 | 54 | parts = publish_parts(source=value, writer_name="html4css1", settings_overrides=docutils_settings) |
52 | | return parts["fragment"] |
| 55 | return mark_safe(parts["fragment"]) |
| 56 | restructuredtext.is_safe = True |
53 | 57 | |
54 | 58 | register.filter(textile) |
55 | 59 | register.filter(markdown) |
diff --git a/django/views/debug.py b/django/views/debug.py
index 77b6c2fac2caa9e554fadbb61cfdd8b955948c63..31215429022e41905618d02034daf14674bb3893 100644
a
|
b
|
TECHNICAL_500_TEMPLATE = """
|
290 | 290 | </script> |
291 | 291 | </head> |
292 | 292 | <body> |
293 | | |
| 293 | {% autoescape %} |
294 | 294 | <div id="summary"> |
295 | 295 | <h1>{{ exception_type }} at {{ request.path|escape }}</h1> |
296 | 296 | <h2>{{ exception_value|escape }}</h2> |
… |
… |
TECHNICAL_500_TEMPLATE = """
|
338 | 338 | <div id="template"> |
339 | 339 | <h2>Template error</h2> |
340 | 340 | <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p> |
341 | | <h3>{{ template_info.message|escape }}</h3> |
| 341 | <h3>{{ template_info.message }}</h3> |
342 | 342 | <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}"> |
343 | 343 | {% for source_line in template_info.source_lines %} |
344 | 344 | {% ifequal source_line.0 template_info.line %} |
… |
… |
TECHNICAL_500_TEMPLATE = """
|
365 | 365 | {% if frame.context_line %} |
366 | 366 | <div class="context" id="c{{ frame.id }}"> |
367 | 367 | {% if frame.pre_context %} |
368 | | <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> |
| 368 | <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> |
369 | 369 | {% endif %} |
370 | | <ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line|escape }} <span>...</span></li></ol> |
| 370 | <ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line }} <span>...</span></li></ol> |
371 | 371 | {% if frame.post_context %} |
372 | | <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> |
| 372 | <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> |
373 | 373 | {% endif %} |
374 | 374 | </div> |
375 | 375 | {% endif %} |
… |
… |
TECHNICAL_500_TEMPLATE = """
|
389 | 389 | {% for var in frame.vars|dictsort:"0" %} |
390 | 390 | <tr> |
391 | 391 | <td>{{ var.0 }}</td> |
392 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| 392 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
393 | 393 | </tr> |
394 | 394 | {% endfor %} |
395 | 395 | </tbody> |
… |
… |
Traceback (most recent call last):<br/>
|
409 | 409 | {% for frame in frames %} |
410 | 410 | File "{{ frame.filename }}" in {{ frame.function }}<br/> |
411 | 411 | {% if frame.context_line %} |
412 | | {{ frame.lineno }}. {{ frame.context_line|escape }}<br/> |
| 412 | {{ frame.lineno }}. {{ frame.context_line }}<br/> |
413 | 413 | {% endif %} |
414 | 414 | {% endfor %}<br/> |
415 | 415 | {{ exception_type }} at {{ request.path|escape }}<br/> |
… |
… |
Traceback (most recent call last):<br/>
|
437 | 437 | {% for var in request.GET.items %} |
438 | 438 | <tr> |
439 | 439 | <td>{{ var.0 }}</td> |
440 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| 440 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
441 | 441 | </tr> |
442 | 442 | {% endfor %} |
443 | 443 | </tbody> |
… |
… |
Traceback (most recent call last):<br/>
|
459 | 459 | {% for var in request.POST.items %} |
460 | 460 | <tr> |
461 | 461 | <td>{{ var.0 }}</td> |
462 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| 462 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
463 | 463 | </tr> |
464 | 464 | {% endfor %} |
465 | 465 | </tbody> |
… |
… |
Traceback (most recent call last):<br/>
|
481 | 481 | {% for var in request.COOKIES.items %} |
482 | 482 | <tr> |
483 | 483 | <td>{{ var.0 }}</td> |
484 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| 484 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
485 | 485 | </tr> |
486 | 486 | {% endfor %} |
487 | 487 | </tbody> |
… |
… |
Traceback (most recent call last):<br/>
|
502 | 502 | {% for var in request.META.items|dictsort:"0" %} |
503 | 503 | <tr> |
504 | 504 | <td>{{ var.0 }}</td> |
505 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| 505 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
506 | 506 | </tr> |
507 | 507 | {% endfor %} |
508 | 508 | </tbody> |
… |
… |
Traceback (most recent call last):<br/>
|
521 | 521 | {% for var in settings.items|dictsort:"0" %} |
522 | 522 | <tr> |
523 | 523 | <td>{{ var.0 }}</td> |
524 | | <td class="code"><div>{{ var.1|pprint|escape }}</div></td> |
| 524 | <td class="code"><div>{{ var.1|pprint }}</div></td> |
525 | 525 | </tr> |
526 | 526 | {% endfor %} |
527 | 527 | </tbody> |
… |
… |
Traceback (most recent call last):<br/>
|
536 | 536 | display a standard 500 page. |
537 | 537 | </p> |
538 | 538 | </div> |
539 | | |
| 539 | {% endautoescape %} |
540 | 540 | </body> |
541 | 541 | </html> |
542 | 542 | """ |
… |
… |
TECHNICAL_404_TEMPLATE = """
|
567 | 567 | </style> |
568 | 568 | </head> |
569 | 569 | <body> |
| 570 | {% autoescape %} |
570 | 571 | <div id="summary"> |
571 | 572 | <h1>Page not found <span>(404)</span></h1> |
572 | 573 | <table class="meta"> |
… |
… |
TECHNICAL_404_TEMPLATE = """
|
588 | 589 | </p> |
589 | 590 | <ol> |
590 | 591 | {% for pattern in urlpatterns %} |
591 | | <li>{{ pattern|escape }}</li> |
| 592 | <li>{{ pattern }}</li> |
592 | 593 | {% endfor %} |
593 | 594 | </ol> |
594 | 595 | <p>The current URL, <code>{{ request.path|escape }}</code>, didn't match any of these.</p> |
595 | 596 | {% else %} |
596 | | <p>{{ reason|escape }}</p> |
| 597 | <p>{{ reason }}</p> |
597 | 598 | {% endif %} |
598 | 599 | </div> |
599 | 600 | |
… |
… |
TECHNICAL_404_TEMPLATE = """
|
604 | 605 | will display a standard 404 page. |
605 | 606 | </p> |
606 | 607 | </div> |
| 608 | {% endautoescape %} |
607 | 609 | </body> |
608 | 610 | </html> |
609 | 611 | """ |
… |
… |
EMPTY_URLCONF_TEMPLATE = """
|
638 | 640 | </head> |
639 | 641 | |
640 | 642 | <body> |
| 643 | {% autoescape %} |
641 | 644 | <div id="summary"> |
642 | 645 | <h1>It worked!</h1> |
643 | 646 | <h2>Congratulations on your first Django-powered page.</h2> |
… |
… |
EMPTY_URLCONF_TEMPLATE = """
|
657 | 660 | Django settings file and you haven't configured any URLs. Get to work! |
658 | 661 | </p> |
659 | 662 | </div> |
| 663 | {% endautoescape %} |
660 | 664 | </body></html> |
661 | 665 | """ |