Merge branch '7.0.x'

This commit is contained in:
Sam Brannen
2026-07-29 22:07:54 +03:00
10 changed files with 134 additions and 0 deletions
@@ -286,6 +286,46 @@ registering property accessors, resolvers, variables, or functions to ensure
of the objects reachable via the context expose operations that would be dangerous if
invoked by an expression from an untrusted source.
[[expressions-evaluation-context-lifecycle]]
=== Lifecycle and Reuse
For performance, the AST nodes that make up a parsed `Expression` may cache the specific
`PropertyAccessor`, `IndexAccessor`, `MethodExecutor`, or `ConstructorExecutor` that
satisfied a previous evaluation, so that later evaluations of the same node can avoid
asking every registered accessor or resolver in turn. Understanding this caching behavior
is essential to using `Expression` and `EvaluationContext` correctly, in addition to the
<<expressions-evaluation-context-security,security considerations>> discussed previously.
A parsed `Expression` is designed to be created once and evaluated repeatedly, and doing
so is both supported and encouraged. In particular:
* A parsed `Expression` may be evaluated against different root objects, and against
different `EvaluationContext` instances of the *same type and with equivalent
configuration* for example, several `StandardEvaluationContext` instances each
registering the same kind of custom `PropertyAccessor`. Changing the accessors or
resolvers registered with a context between evaluations of the same expression is
atypical and generally not advised, but is expected to work correctly: the registered
state of the *current* context is what is consulted, not a snapshot taken during an
earlier evaluation.
* A parsed `Expression` must *not* be evaluated first against a context with one set of
security implications and later against a context with different, typically more
restrictive, security implications for example, first against a
`StandardEvaluationContext` and later against a `SimpleEvaluationContext`. Doing so is
analogous to executing a database query on behalf of an administrator, caching the
resulting administrator-privileged execution plan, and then reusing that cached plan for
a lower-privileged user while expecting the lower-privileged user's restrictions to
apply: cached state from the first, more permissive evaluation may be reused during the
second, and the second context's restrictions cannot be reliably enforced as a result.
If the same expression string must be evaluated under contexts with different security
implications, parse it into *distinct* `Expression` instances, one per context.
[WARNING]
====
Reusing a single parsed `Expression` across `EvaluationContext` instances with different
security implications is not a supported usage pattern and must be avoided, regardless of
which `EvaluationContext` implementations are involved.
====
[[expressions-type-conversion]]
=== Type Conversion