Fixed #17778 -- Prevented class attributes on context from resolving as template variables.

Thanks KyleMac for the report, regebro for the patch, and Aymeric for the test.
This commit is contained in:
Tim Graham 2013-08-12 12:41:39 -04:00
parent 6bdb3b1135
commit 71b5617c24
2 changed files with 14 additions and 2 deletions

View File

@ -6,7 +6,7 @@ from importlib import import_module
from inspect import getargspec from inspect import getargspec
from django.conf import settings from django.conf import settings
from django.template.context import (Context, RequestContext, from django.template.context import (BaseContext, Context, RequestContext,
ContextPopException) ContextPopException)
from django.utils.itercompat import is_iterable from django.utils.itercompat import is_iterable
from django.utils.text import (smart_split, unescape_string_literal, from django.utils.text import (smart_split, unescape_string_literal,
@ -765,6 +765,9 @@ class Variable(object):
current = current[bit] current = current[bit]
except (TypeError, AttributeError, KeyError, ValueError): except (TypeError, AttributeError, KeyError, ValueError):
try: # attribute lookup try: # attribute lookup
# Don't return class attributes if the class is the context:
if isinstance(current, BaseContext) and getattr(type(current), bit):
raise AttributeError
current = getattr(current, bit) current = getattr(current, bit)
except (TypeError, AttributeError): except (TypeError, AttributeError):
try: # list-index lookup try: # list-index lookup

View File

@ -2,7 +2,7 @@
from unittest import TestCase from unittest import TestCase
from django.template import Context from django.template import Context, Variable, VariableDoesNotExist
class ContextTests(TestCase): class ContextTests(TestCase):
@ -25,3 +25,12 @@ class ContextTests(TestCase):
with c.push(a=3): with c.push(a=3):
self.assertEqual(c['a'], 3) self.assertEqual(c['a'], 3)
self.assertEqual(c['a'], 1) self.assertEqual(c['a'], 1)
def test_resolve_on_context_method(self):
# Regression test for #17778
empty_context = Context()
self.assertRaises(VariableDoesNotExist,
Variable('no_such_variable').resolve, empty_context)
self.assertRaises(VariableDoesNotExist,
Variable('new').resolve, empty_context)
self.assertEqual(Variable('new').resolve(Context({'new': 'foo'})), 'foo')