Ticket #17419: 17419-insecure-do-not-use-this.patch

File 17419-insecure-do-not-use-this.patch, 6.5 KB (added by Aymeric Augustin, 12 years ago)
  • django/template/defaultfilters.py

    diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
    index 55aa10d..143d068 100644
    a b  
    11"""Default variable filters."""
    22
     3import json
    34import re
    45import random as random_module
    56import unicodedata
    def filesizeformat(bytes):  
    838839        return ugettext("%s TB") % filesize_number_format(bytes / (1024 * 1024 * 1024 * 1024))
    839840    return ugettext("%s PB") % filesize_number_format(bytes / (1024 * 1024 * 1024 * 1024 * 1024))
    840841
     842def _recursive_escape(value, esc=conditional_escape):
     843    """Recursively escapes strings in an object.
     844
     845    Traverses dict, list and tuples. These are the data structures supported
     846    by the JSON encoder.
     847    """
     848
     849    if isinstance(value, dict):
     850        return type(value)((esc(k), esc(v)) for (k, v) in value.iteritems())
     851    elif isinstance(value, (list, tuple)):
     852        return type(value)(esc(v) for v in value)
     853    elif isinstance(value, (str, unicode)):
     854        return esc(value)
     855    elif isinstance(value, (int, long, float)) or value in (True, False, None):
     856        return value
     857    # We've exhausted all the types acceptable by the default JSON encoder.
     858    # Django's improved JSON encoder handles a few other types, all of which
     859    # are represented by strings. For these types, we apply JSON encoding
     860    # immediately and then escape the result.
     861    else:
     862        # Importing this at the top level causes an import loop.
     863        from django.core.serializers.json import DjangoJSONEncoder
     864        return esc(DjangoJSONEncoder().default(value))
     865
     866@register.filter("json", needs_autoescape=True)
     867def json_filter(value, autoescape=None):
     868    """
     869    Returns the JSON representation of the value.
     870    """
     871    try:
     872        # Importing this at the top level causes an import loop.
     873        from django.core.serializers.json import DjangoJSONEncoder
     874        # If value contains custom subclasses of int, str, datetime, etc.
     875        # arbitrary exceptions may be raised during escaping or serialization.
     876        if autoescape:
     877            value = _recursive_escape(value)
     878        result = json.dumps(value, cls=DjangoJSONEncoder)
     879    except Exception:
     880        return ''
     881    return mark_safe(result)
     882
    841883@register.filter(is_safe=False)
    842884def pluralize(value, arg=u's'):
    843885    """
  • docs/ref/templates/builtins.txt

    diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
    index 5019963..112e0a2 100644
    a b For example::  
    16021602If ``value`` is the list ``['a', 'b', 'c']``, the output will be the string
    16031603``"a // b // c"``.
    16041604
     1605.. templatefilter:: json
     1606
     1607json
     1608^^^^
     1609
     1610.. versionadded:: 1.5
     1611
     1612Converts a Python data structure into a JSON string.
     1613
     1614For example::
     1615
     1616    {{ value|json }}
     1617
     1618If ``value`` is the Python dict ``{u'hello': (u'world', u'wide')}``, the
     1619output will be the string ``'{"hello": ["world", "wide"]}'``.
     1620
    16051621.. templatefilter:: last
    16061622
    16071623last
  • docs/releases/1.5.txt

    diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
    index 5a92e7d..70b3f4b 100644
    a b version compatible with Python 2.6.  
    3333What's new in Django 1.5
    3434========================
    3535
     36``json`` template filter
     37~~~~~~~~~~~~~~~~~~~~~~~~
     38
     39This new filter turns an arbitrary Python object into a JSON string. It's
     40handy to pass data to JavaScript without resorting to an AJAX call. It's also
     41useful when both your HTML and your JavaScript use the same data, for instance
     42when you're displaying a graph and the corresponding data table. See the
     43documentation for :tfilter:`json` for more information.
     44
    3645Minor features
    3746~~~~~~~~~~~~~~
    3847
  • tests/regressiontests/templates/filters.py

    diff --git a/tests/regressiontests/templates/filters.py b/tests/regressiontests/templates/filters.py
    index 41f8e43..ef0918f 100644
    a b def get_filter_tests():  
    106106        'filter-lower01': ("{% autoescape off %}{{ a|lower }} {{ b|lower }}{% endautoescape %}", {"a": "Apple & banana", "b": mark_safe("Apple & banana")}, u"apple & banana apple & banana"),
    107107        'filter-lower02': ("{{ a|lower }} {{ b|lower }}", {"a": "Apple & banana", "b": mark_safe("Apple & banana")}, u"apple & banana apple & banana"),
    108108
     109        # The output of "json" is escaped according to the current
     110        # autoescape setting
     111        'filter-json01': ("{{ data|json }}", {"data": "</script><script>alert('spam');"}, u'"&lt;/script&gt;&lt;script&gt;alert(&#39;spam&#39;);"'),
     112        'filter-json02': ("{% autoescape off %}{{ data|json }}{% endautoescape %}", {"data": "</script><script>alert('spam');"}, u'"</script><script>alert(\'spam\');"'),
     113        'filter-json03': ("{{ data|json }}", {"data": Exception}, u''),
     114
    109115        # The make_list filter can destroy existing escaping, so the results are
    110116        # escaped.
    111117        'filter-make_list01': ("{% autoescape off %}{{ a|make_list }}{% endautoescape %}", {"a": mark_safe("&")}, u"[u'&']"),
    def get_filter_tests():  
    336342        'join04': (r'{% autoescape off %}{{ a|join:" &amp; " }}{% endautoescape %}', {'a': ['alpha', 'beta & me']}, 'alpha &amp; beta & me'),
    337343
    338344        # Test that joining with unsafe joiners don't result in unsafe strings (#11377)
    339         'join05': (r'{{ a|join:var }}', {'a': ['alpha', 'beta & me'], 'var': ' & '}, 'alpha &amp; beta &amp; me'), 
    340         'join06': (r'{{ a|join:var }}', {'a': ['alpha', 'beta & me'], 'var': mark_safe(' & ')}, 'alpha & beta &amp; me'), 
    341         'join07': (r'{{ a|join:var|lower }}', {'a': ['Alpha', 'Beta & me'], 'var': ' & ' }, 'alpha &amp; beta &amp; me'), 
    342         'join08': (r'{{ a|join:var|lower }}', {'a': ['Alpha', 'Beta & me'], 'var': mark_safe(' & ')}, 'alpha & beta &amp; me'), 
    343        
     345        'join05': (r'{{ a|join:var }}', {'a': ['alpha', 'beta & me'], 'var': ' & '}, 'alpha &amp; beta &amp; me'),
     346        'join06': (r'{{ a|join:var }}', {'a': ['alpha', 'beta & me'], 'var': mark_safe(' & ')}, 'alpha & beta &amp; me'),
     347        'join07': (r'{{ a|join:var|lower }}', {'a': ['Alpha', 'Beta & me'], 'var': ' & ' }, 'alpha &amp; beta &amp; me'),
     348        'join08': (r'{{ a|join:var|lower }}', {'a': ['Alpha', 'Beta & me'], 'var': mark_safe(' & ')}, 'alpha & beta &amp; me'),
     349
    344350        'date01': (r'{{ d|date:"m" }}', {'d': datetime(2008, 1, 1)}, '01'),
    345351        'date02': (r'{{ d|date }}', {'d': datetime(2008, 1, 1)}, 'Jan. 1, 2008'),
    346352        #Ticket 9520: Make sure |date doesn't blow up on non-dates
Back to Top