fix: Feature flag boolean parsing error (#35551)#35769
Conversation
|
Claude finished @gortiz-dotcms's task in 3m 48s —— View job 🔍 dotCMS Backend Review — Done
Summary of findings
|
|
Pull Request Unsafe to Rollback!!!
|
🔍 dotCMS Backend Review[🟠 High]
import java.io.IOException;💡 Delete the import line. [🟠 High]
* @return
* @throws IOException
*/
@Path("/config")💡 Drop the [🟠 High]
@Path("/config")
@GET
@JSONP
@NoCache
@Produces({MediaType.APPLICATION_JSON, "application/javascript"})
public final Response getConfigVariables(@Context final HttpServletRequest request,💡 Add [🟡 Medium]
@QueryParam("keys") final String keysQuery) {
new WebResource.InitBuilder(webResource)...init();
final String[] keys = StringUtils.splitByCommas(keysQuery);
final Map<String,Object> resultMap = new LinkedHashMap<>();
if (null != keys) {💡 Replace the null check with Items verified clean
Next steps
|
…x Logger, harden test (#35551) - Add FeatureFlagName.FEATURE_FLAG_CONTENT_EDITOR2_ENABLED constant and replace two hardcoded "CONTENT_EDITOR2_ENABLED" literals in ConfigurationResource - Add maintenance warning to BOOLEAN_FEATURE_FLAGS Javadoc explaining the dual-list rule - Use Logger.warn lambda form to avoid eager string concatenation when WARN is filtered - Make dot-custom-event-handler tolerant of both boolean true and legacy string 'true' to eliminate rollback-window regression (M-3 concern) - Replace fragile SOME_INTERNAL_SECRET test key with a UUID-shaped string that can never be accidentally added to WHITE_LIST Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tic init (#35551) mockStatic(Config.class) inside each try block was intercepting Config.getStringProperty called by JVMInfoResource's static initializer (Pattern.compile) and returning null for the unstubbed call, causing Pattern.compile(null) → NullPointerException. Fix: open the Config mock at @BeforeEach/@AfterEach level with a default answer that returns the caller-supplied default for any unstubbed getStringProperty call, preventing JVMInfoResource from receiving null when it first loads. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Pull Request Unsafe to Rollback!!!
|
… booleans (#35551) Changing the wire format from string to boolean broke the existing Postman contract tests (which assert typeof value === 'string') and introduced an M-3 rollback risk for any consumer built against the original string-typed contract. parseBooleanFlag now returns the canonical lowercase strings "true" / "false" / "NOT_FOUND" instead of Boolean.TRUE / Boolean.FALSE. This fully fixes the original bug (case-insensitive handling of "True", "TRUE", "1", etc.) without changing the API contract that existing callers depend on. Unit test expectations updated to match the string wire format. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Fixes #35551 — Feature flag boolean parsing is case-sensitive.
ConfigurationResource):recoveryFromConfigpreviously fell through toConfig.getStringPropertyfor all unprefixedFEATURE_FLAG_*keys, returning raw strings ("True","FALSE","1") that the frontend could not reliably coerce. A newBOOLEAN_FEATURE_FLAGSset identifies every boolean flag in the whitelist. For those keys, a dedicatedparseBooleanFlaghelper now resolves the value to a native JSONBoolean, handling all industry-standard truthy/falsy variants (case-insensitive, whitespace-trimmed), and preserves the"NOT_FOUND"sentinel for keys that are not defined anywhere on the server. Unrecognised values log aWARNand resolve tofalse.DotCustomEventHandlerService): TheCONTENT_EDITOR2_ENABLEDflag check was a strict string comparison (=== 'true') that silently breaks once the backend returns a native boolean. Updated to=== true.ConfigurationResource): Added constructor injection ofWebResource(package-private, following the same pattern asPageScannerResourceandReportIssueResource) so the endpoint can be tested without a running container.Accepted truthy/falsy values
true,True,TRUE,truetrue1truefalse,False,FALSE,falsefalse0, `` (empty)false"NOT_FOUND"(sentinel preserved for frontend opt-out logic)false+WARNlogTest plan
ConfigurationResourceTest(new unit test indotCMS/src/test/java) — covers all truthy/falsy variants,NOT_FOUNDsentinel, whitelist exclusion, and raw-string passthrough for non-flag keys. Runs without a container viamockStatic(Config.class)and injectedWebResource.dotcms-integration/.../ConfigurationResourceTestcontinues to pass unchanged.FEATURE_FLAG_UVE_TOGGLE_LOCK=True(capitalised), restart, callGET /api/v1/configuration/config?keys=FEATURE_FLAG_UVE_TOGGLE_LOCK— response now contains native booleantrueand the UVE lock/unlock button renders.🤖 Generated with Claude Code