diff options
author | Tomas Krizek <tomas.krizek@mailbox.org> | 2020-02-03 23:25:56 +0100 |
---|---|---|
committer | David Lord <davidism@gmail.com> | 2020-02-04 08:37:58 -0800 |
commit | 9933324688170a7037a764717b4e88adefaf4101 (patch) | |
tree | 0ecc357476675e5e7fc015be4a9a300a3322f375 /src | |
parent | 3d5bfc6109bcc682f5266b118180e8b5fb775ae9 (diff) | |
download | jinja-9933324688170a7037a764717b4e88adefaf4101.tar.gz |
Use stricter getattr() checks for decorator functions
Explicit checks for "is True" prevents unexpected behaviour with objects
that are callable and have permissive gettatr(), such as Mock.
Fixes #1145
Diffstat (limited to 'src')
-rw-r--r-- | src/jinja2/asyncfilters.py | 9 | ||||
-rw-r--r-- | src/jinja2/compiler.py | 12 | ||||
-rw-r--r-- | src/jinja2/environment.py | 6 | ||||
-rw-r--r-- | src/jinja2/nodes.py | 6 | ||||
-rw-r--r-- | src/jinja2/runtime.py | 6 |
5 files changed, 19 insertions, 20 deletions
diff --git a/src/jinja2/asyncfilters.py b/src/jinja2/asyncfilters.py index d29f6c62..3d98dbcc 100644 --- a/src/jinja2/asyncfilters.py +++ b/src/jinja2/asyncfilters.py @@ -26,17 +26,16 @@ async def async_select_or_reject(args, kwargs, modfunc, lookup_attr): def dualfilter(normal_filter, async_filter): wrap_evalctx = False - if getattr(normal_filter, "environmentfilter", False): + if getattr(normal_filter, "environmentfilter", False) is True: def is_async(args): return args[0].is_async wrap_evalctx = False else: - if not getattr(normal_filter, "evalcontextfilter", False) and not getattr( - normal_filter, "contextfilter", False - ): - wrap_evalctx = True + has_evalctxfilter = getattr(normal_filter, "evalcontextfilter", False) is True + has_ctxfilter = getattr(normal_filter, "contextfilter", False) is True + wrap_evalctx = not has_evalctxfilter and not has_ctxfilter def is_async(args): return args[0].environment.is_async diff --git a/src/jinja2/compiler.py b/src/jinja2/compiler.py index f450ec6e..63297b42 100644 --- a/src/jinja2/compiler.py +++ b/src/jinja2/compiler.py @@ -1307,13 +1307,13 @@ class CodeGenerator(NodeVisitor): def finalize(value): return default(env_finalize(value)) - if getattr(env_finalize, "contextfunction", False): + if getattr(env_finalize, "contextfunction", False) is True: src += "context, " finalize = None # noqa: F811 - elif getattr(env_finalize, "evalcontextfunction", False): + elif getattr(env_finalize, "evalcontextfunction", False) is True: src += "context.eval_ctx, " finalize = None - elif getattr(env_finalize, "environmentfunction", False): + elif getattr(env_finalize, "environmentfunction", False) is True: src += "environment, " def finalize(value): @@ -1689,11 +1689,11 @@ class CodeGenerator(NodeVisitor): func = self.environment.filters.get(node.name) if func is None: self.fail("no filter named %r" % node.name, node.lineno) - if getattr(func, "contextfilter", False): + if getattr(func, "contextfilter", False) is True: self.write("context, ") - elif getattr(func, "evalcontextfilter", False): + elif getattr(func, "evalcontextfilter", False) is True: self.write("context.eval_ctx, ") - elif getattr(func, "environmentfilter", False): + elif getattr(func, "environmentfilter", False) is True: self.write("environment, ") # if the filter node is None we are inside a filter block diff --git a/src/jinja2/environment.py b/src/jinja2/environment.py index bf44b9de..8430390e 100644 --- a/src/jinja2/environment.py +++ b/src/jinja2/environment.py @@ -492,20 +492,20 @@ class Environment(object): if func is None: fail_for_missing_callable("no filter named %r", name) args = [value] + list(args or ()) - if getattr(func, "contextfilter", False): + if getattr(func, "contextfilter", False) is True: if context is None: raise TemplateRuntimeError( "Attempted to invoke context filter without context" ) args.insert(0, context) - elif getattr(func, "evalcontextfilter", False): + elif getattr(func, "evalcontextfilter", False) is True: if eval_ctx is None: if context is not None: eval_ctx = context.eval_ctx else: eval_ctx = EvalContext(self) args.insert(0, eval_ctx) - elif getattr(func, "environmentfilter", False): + elif getattr(func, "environmentfilter", False) is True: args.insert(0, self) return func(*args, **(kwargs or {})) diff --git a/src/jinja2/nodes.py b/src/jinja2/nodes.py index 9f3edc05..95bd614a 100644 --- a/src/jinja2/nodes.py +++ b/src/jinja2/nodes.py @@ -671,7 +671,7 @@ class Filter(Expr): # python 3. because of that, do not rename filter_ to filter! filter_ = self.environment.filters.get(self.name) - if filter_ is None or getattr(filter_, "contextfilter", False): + if filter_ is None or getattr(filter_, "contextfilter", False) is True: raise Impossible() # We cannot constant handle async filters, so we need to make sure @@ -684,9 +684,9 @@ class Filter(Expr): args, kwargs = args_as_const(self, eval_ctx) args.insert(0, self.node.as_const(eval_ctx)) - if getattr(filter_, "evalcontextfilter", False): + if getattr(filter_, "evalcontextfilter", False) is True: args.insert(0, eval_ctx) - elif getattr(filter_, "environmentfilter", False): + elif getattr(filter_, "environmentfilter", False) is True: args.insert(0, self.environment) try: diff --git a/src/jinja2/runtime.py b/src/jinja2/runtime.py index 527d4b5e..3ad79686 100644 --- a/src/jinja2/runtime.py +++ b/src/jinja2/runtime.py @@ -280,11 +280,11 @@ class Context(with_metaclass(ContextMeta)): break if callable(__obj): - if getattr(__obj, "contextfunction", 0): + if getattr(__obj, "contextfunction", False) is True: args = (__self,) + args - elif getattr(__obj, "evalcontextfunction", 0): + elif getattr(__obj, "evalcontextfunction", False) is True: args = (__self.eval_ctx,) + args - elif getattr(__obj, "environmentfunction", 0): + elif getattr(__obj, "environmentfunction", False) is True: args = (__self.environment,) + args try: return __obj(*args, **kwargs) |