Restrict freemarker ObjectWrapper instrumentation to 2.3.24+ - #12117
Restrict freemarker ObjectWrapper instrumentation to 2.3.24+#12117AlexeyKuznetsov-DD wants to merge 1 commit into
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
More details
The added classloader guard matches the existing Freemarker version split: ObjectWrapper advice remains active for 2.3.24+ and is excluded from older versions, while the 2.3.9 instrumentation remains responsible for its supported range. Runtime tests could not start because the required Gradle distribution was unavailable in the sandbox.
🤖 Datadog Autotest · Commit d7add24 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d7add24479
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| static final ElementMatcher.Junction<ClassLoader> VERSION_POST_2_3_24 = | ||
| hasClassNamed("freemarker.cache.ByteArrayTemplateLoader"); |
There was a problem hiding this comment.
Return the class-loader matcher directly
When this instrumentation is registered, classLoaderMatcher() is invoked only once, so caching its result in VERSION_POST_2_3_24 adds static state and constant-pool bloat without reuse. docs/instrumentation_design_guidelines.md explicitly requires one-shot matcher values to be constructed and returned directly; inline hasClassNamed(...) in classLoaderMatcher() instead.
AGENTS.md reference: AGENTS.md:L40-L44
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| static final ElementMatcher.Junction<ClassLoader> VERSION_POST_2_3_24 = | ||
| hasClassNamed("freemarker.cache.ByteArrayTemplateLoader"); |
There was a problem hiding this comment.
Gate hierarchy implementations on a visible package
When a custom ObjectWrapper implementation is loaded by an OSGi bundle that imports freemarker.template but not freemarker.cache, this matcher is evaluated against the implementation's bundle class loader and cannot see ByteArrayTemplateLoader. BundleWiringHelper.probeResource() only reports resources from directly imported packages, so the new module-wide guard rejects the transformation even with FreeMarker 2.3.24+, silently disabling the IAST taint propagation for that wrapper; use a version marker visible through the same imported package or a gate that does not require the unrelated cache package.
Useful? React with 👍 / 👎.
|
🎯 Code Coverage (details) 🔗 Commit SHA: d7add24 | Docs | Datadog PR Page | Give us feedback! |
🟡 Java Benchmark SLOs — Performance SLO warning (near threshold)
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
DO NOT MERGE, first need to decide how to fix correctly.
What Does This Do
Adds a classloader version guard to
ObjectWrapperInstrumentation(freemarker2.3.24module), matching whatDollarVariableInstrumentationalready does in the same package:Motivation
The
freemarker-2.3.24muzzle directive declaresversions = '[2.3.24-incubating,]'withassertInverse = true, so every pre-2.3.24version is expected to fail muzzle.ObjectWrapperInstrumentationonly referencesfreemarker.template.ObjectWrapperandfreemarker.template.TemplateModel, both of which exist since2.3.9— so its reference check passed on old versions and the inverse assertion blew up with:MuzzleVersionScanPluginfolds the classloader matcher into the pass/fail verdict (passed = mismatches.isEmpty() && classLoaderMatch), so adding the guard makes the instrumentation fail muzzle on pre-2.3.24as declared. This showed up only intermittently on GitLab because muzzle samples the inverse version range randomly (MuzzleVersionUtils.limitLargeRangesshuffles low/high permajor.minor).Additional Notes
freemarker.cache.ByteArrayTemplateLoaderwas verified as the right version marker: absent in2.3.9/2.3.20/2.3.23, present in2.3.24-incubating/2.3.34.MAVEN_REPOSITORY_PROXYat a file repo exposing2.3.23in its metadata (maven central'sorg.freemarker:freemarkermetadata only lists2.3.24+, which is why the inverse range is empty on plain central):muzzle-AssertFail-...-2.3.23fails without this change and passes with it.2.3.9–2.3.23theObjectWrappertaint propagation no longer applies, aligning behavior with the module's declared support range. The2.3.9module ships noObjectWrapperinstrumentation, so no tested version loses coverage.freemarker-2.3.24test/latestDepTestandfreemarker-2.3.9test/version2_3_23Testall pass (42 tests).🤖 Generated with Claude Code