[stable-2.19] ensure undefined marker access on Jinja getattr->getitem fallback (#85688) (#85691)

(cherry picked from commit 3518d48146)

Co-authored-by: Matt Davis <6775756+nitzmahone@users.noreply.github.com>
pull/85694/head
Matt Clay 4 months ago committed by GitHub
parent 6404fdce45
commit a00261b0ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,4 @@
bugfixes:
- templating - Undefined marker values sourced from the Jinja ``getattr->getitem`` fallback are now accessed correctly,
raising AnsibleUndefinedVariable for user plugins that do not understand markers.
Previously, these values were erroneously returned to user plugin code that had not opted in to marker acceptance.

@ -811,7 +811,7 @@ class AnsibleEnvironment(SandboxedEnvironment):
try:
value = obj[attribute]
except (TypeError, LookupError):
return self.undefined(obj=obj, name=attribute) if is_safe else self.unsafe_undefined(obj, attribute)
value = self.undefined(obj=obj, name=attribute) if is_safe else self.unsafe_undefined(obj, attribute)
AnsibleAccessContext.current().access(value)

@ -12,7 +12,7 @@ import pytest_mock
from ansible.errors import AnsibleUndefinedVariable, AnsibleTemplateError
from ansible._internal._templating._errors import AnsibleTemplatePluginRuntimeError
from ansible.module_utils._internal._datatag import AnsibleTaggedObject
from ansible._internal._templating._jinja_common import CapturedExceptionMarker, MarkerError, Marker, UndefinedMarker
from ansible._internal._templating._jinja_common import CapturedExceptionMarker, MarkerError, Marker, UndefinedMarker, JinjaCallContext
from ansible._internal._templating._utils import TemplateContext
from ansible._internal._datatag._tags import TrustedAsTemplate
from ansible._internal._templating._jinja_bits import (AnsibleEnvironment, TemplateOverrides, _TEMPLATE_OVERRIDE_FIELD_NAMES, defer_template_error,
@ -443,3 +443,17 @@ def test_mutation_methods(template: str, result: object) -> None:
This feature may be deprecated and removed in a future release by using Jinja's ImmutableSandboxedEnvironment.
"""
assert TemplateEngine().template(TRUST.tag(template)) == result
@pytest.mark.parametrize("template", (
'{{ adict["bogus"] | default("ok") }}',
'{{ adict.bogus | default("ok") }}',
))
def test_marker_access_getattr_and_getitem(template: str) -> None:
"""Ensure that getattr and getitem always access markers."""
# the absence of a JinjaCallContext should cause the access done by getattr and getitem not to trip when a marker is encountered
assert TemplateEngine(variables=dict(adict={})).template(TRUST.tag(template)) == "ok"
with pytest.raises(AnsibleUndefinedVariable):
with JinjaCallContext(accept_lazy_markers=False): # the access done by getattr and getitem should immediately trip when a marker is encountered
TemplateEngine(variables=dict(adict={})).template(TRUST.tag(template))

Loading…
Cancel
Save