Skip to content

return null for malformed input in UrlDecoderStringLookup#749

Open
dxbjavid wants to merge 1 commit into
apache:masterfrom
dxbjavid:urldecoder-malformed-null
Open

return null for malformed input in UrlDecoderStringLookup#749
dxbjavid wants to merge 1 commit into
apache:masterfrom
dxbjavid:urldecoder-malformed-null

Conversation

@dxbjavid
Copy link
Copy Markdown
Contributor

@dxbjavid dxbjavid commented Jun 3, 2026

UrlDecoderStringLookup.lookup only catches UnsupportedEncodingException, so a malformed percent-escape like ${urlDecoder:%} lets URLDecoder.decode throw IllegalArgumentException straight out of StringSubstitutor.replace on the default interpolator. The sibling decoder lookups already swallow that: FunctionStringLookup catches IllegalArgumentException and returns null, so ${base64Decoder:!} just resolves to nothing. Catch it here too and return null so malformed untrusted input decodes consistently.

@garydgregory
Copy link
Copy Markdown
Member

This needs further study since the all lookups in this package might handle certain exception inconsistently while others should propagate exceptions (and already do).

@dxbjavid
Copy link
Copy Markdown
Contributor Author

dxbjavid commented Jun 3, 2026

had a proper read through the package before replying. on bad input the lookups split into two camps:

  • value transforms that squelch to null so the interpolator can fall through to a default: base64Decoder/base64Encoder via FunctionStringLookup (catches IllegalArgumentException), resourceBundle (MissingResourceException), dns and inetAddress (UnknownHostException), constant (Exception).
  • operational lookups that deliberately surface failures as IllegalArgumentException: script, url, file, properties, xml. those load or run something so propagating reads as correct, and i've left all of them untouched.

urlDecoder belongs in the first camp next to its closest sibling base64Decoder, which already returns null on malformed input. at the moment it's the odd one out: it handles the UnsupportedEncodingException path but lets URLDecoder.decode's IllegalArgumentException on a bad percent-escape (${urlDecoder:%}) propagate straight out of StringSubstitutor.replace, whereas ${base64Decoder:!} just resolves to nothing. the patch only brings urlDecoder in line with that, so nothing in the propagate camp changes.

i also checked urlEncoder for symmetry, but URLEncoder.encode doesn't throw IllegalArgumentException on arbitrary input so it doesn't need the same guard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants