]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
Use stricter getattr() checks for decorator functions
authorTomas Krizek <tomas.krizek@mailbox.org>
Mon, 3 Feb 2020 22:25:56 +0000 (23:25 +0100)
committerDavid Lord <davidism@gmail.com>
Tue, 4 Feb 2020 16:37:58 +0000 (08:37 -0800)
Explicit checks for "is True" prevents unexpected behaviour with objects
that are callable and have permissive gettatr(), such as Mock.

Fixes #1145

src/jinja2/asyncfilters.py
src/jinja2/compiler.py
src/jinja2/environment.py
src/jinja2/nodes.py
src/jinja2/runtime.py

index d29f6c62d2e51ba0fddda927c0a04d934da1118c..3d98dbcc00de104a584b0707df8f0d4e8bbe1376 100644 (file)
@@ -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
index f450ec6e314d5e4f5ab245c743497882f49c2238..63297b42c30f17b0c0ae08547047d070e7a53d3c 100644 (file)
@@ -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
index bf44b9deb4a14217d3b1177be8102544ed6ba88c..8430390eeab412b7f3b92d88a4bdecbe1de5f538 100644 (file)
@@ -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 {}))
 
index 9f3edc05f9f3b2e58f341aa3cad94cb91e437152..95bd614a140a8cd8da3642831650215c7e8ac105 100644 (file)
@@ -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:
index 527d4b5e4bf280103b61c3a8edf9f2c9a58cff45..3ad79686242d35b2ce587ac8267259621d4769e4 100644 (file)
@@ -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)