From 5354235bac153340ea17903b083910d83dfb638c Mon Sep 17 00:00:00 2001 From: Michael Libbe Date: Mon, 30 Mar 2026 13:51:54 -0400 Subject: [PATCH] fix: catch IllegalArgumentException in $canonicalize for malformed % sequences Lucee's Canonicalize() delegates to Java's URLDecoder.decode(), which throws java.lang.IllegalArgumentException when the input contains %% or any lone % not followed by two hex digits. This crashes form rendering whenever CFWheels re-populates a field (e.g. after validation failure) with a value containing such characters. Passwords are a common real-world trigger: a user entering P%%ssword or 100%%secure will always hit this crash on form re-render. Wrap the Canonicalize() call in try/catch and fall back to the raw input on failure. The raw value is safe because the caller (miscellaneous.cfc:457) always passes it through EncodeForHTMLAttribute() immediately after. The existing null-check guard for Lucee 5 is preserved inside the try block. --- vendor/wheels/Global.cfc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/vendor/wheels/Global.cfc b/vendor/wheels/Global.cfc index dce225790..2f821ec78 100644 --- a/vendor/wheels/Global.cfc +++ b/vendor/wheels/Global.cfc @@ -2343,9 +2343,17 @@ component output="false" { * Call CFML's canonicalize() function but set to blank string if the result is null (happens on Lucee 5). */ public string function $canonicalize(required string input) { - local.rv = Canonicalize(arguments.input, false, false); - if (IsNull(local.rv)) { - local.rv = ""; + try { + local.rv = Canonicalize(arguments.input, false, false); + if (IsNull(local.rv)) { + local.rv = ""; + } + } catch (any e) { + // Lucee's Canonicalize() delegates to Java's URLDecoder, which throws + // IllegalArgumentException for inputs containing malformed percent-encoded + // sequences (e.g. %% or a lone % not followed by two hex digits). + // Fall back to the raw input; it will still be HTML-encoded by the caller. + local.rv = arguments.input; } return local.rv; }