feat: allowlist enum method invocation and return types#1323
Merged
Conversation
Enum values with constant-specific class bodies are realized at runtime as anonymous subclasses (e.g. Op$1) whose getCanonicalName() returns null. The method and return-type allowlists key off canonical class name, so they bailed on null and such enums could never be allowlisted even when the user explicitly added the enum type. Resolve the runtime enum-constant class to its base enum type before the canonical-name check so allowlisting a specific enum works for its values and methods, including constant-specific bodies. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jaredstehler
approved these changes
Jul 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR description was authored by Claude Code.
jinjava sandboxes template rendering with two allowlists — a method allowlist and a return-type allowlist — both of which match a value's canonical class name against configured names/prefixes.
A simple enum (
enum Color { RED, GREEN }) could already be allowlisted by adding its canonical class name. But an enum with a constant-specific class body (enum Op { PLUS { int apply(){...} } }) is realized at runtime as an anonymous subclass (Op$1) whosegetCanonicalName()returnsnull. Both validators bail on anullcanonical name, so these enums — their values and their overridden methods — could never be allowlisted, even when the caller explicitly added the enum type.This change resolves the runtime enum-constant class to its base enum type before the existing canonical-name check, so allowlisting a specific enum by class name works for its values and methods, including constant-specific bodies.
Scope is intentionally narrow: specific enums only. No blanket "allow all enums" toggle, no new builder helper, no new
AllowlistGroup— just correct resolution of the value/method class back to the enum type the caller already allowlisted.AllowlistReturnTypeValidator: when the value is an enum, validate against((Enum<?>) o).getDeclaringClass()instead of the runtime class.AllowlistMethodValidator: when a method's declaring class has anullcanonical name and its superclass is an enum, use the enum type's canonical name for the check.Both are no-ops for simple enums and non-enum values.
BRAVE
Backwards Compatibility
nullcanonical name.Rollout and Rollback Plan
Automated Testing
AllowlistEnumTest(9 tests): direct validator checks for a simple enum and a constant-specific-body enum, rejection of a non-allowlisted enum (java.time.Month), and end-to-end renders ({{ op.apply(2, 3) }}→5,{{ color.label }},{{ op }}→ name). The constant-body method test pins the regression by asserting the declaring class canonical name isnull.SimpleColorEnumandOperationEnumunder the already-allowlistedtestobjectspackage.com.hubspot.jinjava.el.**suite (236 tests) passes;spotless:checkclean.Verification
mvn -Dtest=AllowlistEnumTest,AllowlistGroupTest,ValidatorConfigBannedConstructsTest test— green.Expect Dependencies to Fail
@Value.Checkguardrails still reject banned classes at config time, so resolution cannot expose anything not already permitted.REVIEWERS: Please review both the code changes and the answers above, and validate that they match the expectations for BRAVE