from jinja.parser import Parser
from jinja.loaders import LoaderWrapper
from jinja.datastructure import Undefined, Markup, Context, FakeTranslator
-from jinja.utils import escape, collect_translations
-from jinja.exceptions import FilterNotFound, TestNotFound
+from jinja.utils import escape, collect_translations, get_attribute
+from jinja.exceptions import FilterNotFound, TestNotFound, SecurityException
from jinja.defaults import DEFAULT_FILTERS, DEFAULT_TESTS, DEFAULT_NAMESPACE
try:
return obj[name]
except (TypeError, KeyError, IndexError):
- if name[:2] == name[-2:] == '__':
- return Undefined
- if not hasattr(obj, name):
- return Undefined
- r = getattr(obj, 'jinja_allowed_attributes', None)
- if r is not None and name not in r:
- return Undefined
- return getattr(obj, name)
+ try:
+ return get_attribute(obj, name)
+ except (AttributeError, SecurityException):
+ pass
return Undefined
def call_function(self, f, context, args, kwargs, dyn_args, dyn_kwargs):
class SecurityException(TemplateError):
"""
Raise if the template designer tried to do something dangerous.
-
- Not used any more. exists for backwards compatibility.
"""
def translate(self):
self.reset()
- rv = self.handle_node(self.node)
- print rv
- return rv
+ return self.handle_node(self.node)
# -- jinja nodes
from compiler.ast import CallFunc, Name, Const
from jinja.nodes import Trans
from jinja.datastructure import Context, TemplateData
+from jinja.exceptions import SecurityException
try:
from collections import deque
return _from_string_env.from_string(source)
+def get_attribute(obj, name):
+ """
+ Return the attribute from name. Raise either `AttributeError`
+ or `SecurityException` if something goes wrong.
+ """
+ if not isinstance(name, basestring):
+ raise AttributeError(name)
+ if name[:2] == name[-2:] == '__' or name[:2] == '::':
+ raise SecurityException('not allowed to access internal attributes')
+ if (obj.__class__ is FunctionType and name.startswith('func_') or
+ obj.__class__ is MethodType and name.startswith('im_')):
+ raise SecurityException('not allowed to access function attributes')
+ r = getattr(obj, 'jinja_allowed_attributes', None)
+ if r is not None and name not in r:
+ raise SecurityException('not allowed attribute accessed')
+ return getattr(obj, name)
+
+
def debug_context(env, context):
"""
Use this function in templates to get a printed context.