Django

Code

Changeset 9442

Show
Ignore:
Timestamp:
11/14/08 19:16:20 (2 months ago)
Author:
mtredinnick
Message:

Fixed #6948 -- The join filter was escaping the literal value that was
passed in for the connector. This was contrary to what the documentation
for autoescaping said and to what every other filter does with literal
strings as arguments.

This is backwards incompatible for the situation of the literal string
containing one of the five special HTML characters: if you were writing
{{ foo|join:"&" }}, you now have to write {{ foo| join:"&" }}.
Previous behaviour was, as noted, a bug and contrary to what was
documented and expected.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/template/defaultfilters.py

    r9369 r9442  
    100100# Values for testing floatformat input against infinity and NaN representations, 
    101101# which differ across platforms and Python versions.  Some (i.e. old Windows 
    102 # ones) are not recognized by Decimal but we want to return them unchanged vs.  
     102# ones) are not recognized by Decimal but we want to return them unchanged vs. 
    103103# returning an empty string as we do for completley invalid input.  Note these 
    104 # need to be built up from values that are not inf/nan, since inf/nan values do  
    105 # not reload properly from .pyc files on Windows prior to some level of Python 2.5  
     104# need to be built up from values that are not inf/nan, since inf/nan values do 
     105# not reload properly from .pyc files on Windows prior to some level of Python 2.5 
    106106# (see Python Issue757815 and Issue1080440). 
    107107pos_inf = 1e200 * 1e200 
     
    137137    * {{ num2|floatformat:"-3" }} displays "34" 
    138138    * {{ num3|floatformat:"-3" }} displays "34.260" 
    139      
     139 
    140140    If the input float is infinity or NaN, the (platform-dependent) string 
    141141    representation of that value will be displayed. 
    142142    """ 
    143          
     143 
    144144    try: 
    145145        input_val = force_unicode(text) 
     
    156156    except ValueError: 
    157157        return input_val 
    158      
     158 
    159159    try: 
    160160        m = int(d) - d 
    161161    except (OverflowError, InvalidOperation): 
    162162        return input_val 
    163      
     163 
    164164    if not m and p < 0: 
    165165        return mark_safe(u'%d' % (int(d))) 
    166      
     166 
    167167    if p == 0: 
    168168        exp = Decimal(1) 
     
    482482first.is_safe = False 
    483483 
    484 def join(value, arg): 
    485     """Joins a list with a string, like Python's ``str.join(list)``.""" 
    486     try: 
    487         data = arg.join(map(force_unicode, value)) 
     484def join(value, arg, autoescape=None): 
     485    """ 
     486    Joins a list with a string, like Python's ``str.join(list)``. 
     487    """ 
     488    if autoescape: 
     489        from django.utils.html import conditional_escape 
     490        value = [conditional_escape(v) for v in value] 
     491    try: 
     492        data = arg.join(value) 
    488493    except AttributeError: # fail silently but nicely 
    489494        return value 
    490     safe_args = reduce(lambda lhs, rhs: lhs and isinstance(rhs, SafeData), 
    491             value, True) 
    492     if safe_args: 
    493         return mark_safe(data) 
    494     else: 
    495         return data 
     495    return mark_safe(data) 
    496496join.is_safe = True 
     497join.needs_autoescape = True 
    497498 
    498499def last(value): 
  • django/trunk/tests/regressiontests/templates/filters.py

    r9291 r9442  
    278278        'escapejs01': (r'{{ a|escapejs }}', {'a': 'testing\r\njavascript \'string" <b>escaping</b>'}, 'testing\\x0D\\x0Ajavascript \\x27string\\x22 \\x3Cb\\x3Eescaping\\x3C/b\\x3E'), 
    279279        'escapejs02': (r'{% autoescape off %}{{ a|escapejs }}{% endautoescape %}', {'a': 'testing\r\njavascript \'string" <b>escaping</b>'}, 'testing\\x0D\\x0Ajavascript \\x27string\\x22 \\x3Cb\\x3Eescaping\\x3C/b\\x3E'), 
    280          
     280 
    281281        # Boolean return value from length_is should not be coerced to a string 
    282282        'lengthis01': (r'{% if "X"|length_is:0 %}Length is 0{% else %}Length not 0{% endif %}', {}, 'Length not 0'), 
    283283        'lengthis02': (r'{% if "X"|length_is:1 %}Length is 1{% else %}Length not 1{% endif %}', {}, 'Length is 1'), 
     284 
     285        'join01': (r'{{ a|join:", " }}', {'a': ['alpha', 'beta & me']}, 'alpha, beta &amp; me'), 
     286        'join02': (r'{% autoescape off %}{{ a|join:", " }}{% endautoescape %}', {'a': ['alpha', 'beta & me']}, 'alpha, beta & me'), 
     287        'join03': (r'{{ a|join:" &amp; " }}', {'a': ['alpha', 'beta & me']}, 'alpha &amp; beta &amp; me'), 
     288        'join04': (r'{% autoescape off %}{{ a|join:" &amp; " }}{% endautoescape %}', {'a': ['alpha', 'beta & me']}, 'alpha &amp; beta & me'), 
    284289    } 
    285290