[
https://issues.apache.org/jira/browse/CAMEL-25453?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
shashank reassigned CAMEL-25453:
--------------------------------
Assignee: shashank
> camel-core - an encoded & (%26) in an endpoint URI option value splits the
> option: URISupport decodes the query before splitting it
> -----------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25453
> URL: https://issues.apache.org/jira/browse/CAMEL-25453
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: shashank
> Assignee: shashank
> Priority: Minor
>
> {{URISupport}} decodes the query of an endpoint URI before it splits it into
> options, so an encoded & ({{%26}}) in a value separates two options:
> ||URI||normalized (endpoint key)||parameters||
> |{{log:foo?marker=Tom%26Jerry}}|{{log://foo?Jerry=&marker=Tom}}|{{marker=Tom}},
> {{Jerry=}}|
> |{{http://host/p?q=a%26b}}|{{http://host/p?b=&q=a}}|{{q=a}}, {{b=}}|
> |{{log:foo?marker=%E2%82%AC%26}}|{{URISyntaxException}}: Trailing & marker
> found| |
> Both {{URISupport.parseParameters(URI)}}, which {{DefaultComponent}} uses to
> configure the endpoint, and the complex normalizer in {{normalizeUri}} take
> the query from {{prepareQuery(URI)}}, which is {{URI.getQuery()}} (or the
> decoded scheme-specific part): every escape is already decoded when the
> {{URIScanner}} splits at {{&}}. The scanner itself does not decode values (it
> escapes {{%}} before {{URLDecoder}}), so an encoded {{&}} cannot survive.
> What users see on main: a component that is not lenient fails to create the
> endpoint ({{log:foo?marker=Tom%26Jerry}}: _There are 1 parameters that
> couldn't be set on the endpoint ... Unknown parameters=[{Jerry=}]_). A
> lenient component such as {{http}} gets the value cut at the {{%26}} plus an
> extra empty parameter.
> *The Endpoint DSL hits this too.* {{AbstractEndpointBuilder.computeUri}}
> encodes option values with {{URISupport.createQueryString}}, which writes
> {{&}} as {{%26}}, and resolves the result as an already normalized URI. So
> {{log("foo").marker("Tom&Jerry")}} builds {{log://foo?marker=Tom%26Jerry}}
> and fails to resolve on main in the same way. CAMEL-24253 fixed the same
> double decoding for {{+}} and {{%}} in Endpoint DSL values by wrapping them
> in {{RAW()}} (a regression of CAMEL-22293 in 4.14.0). {{&}} was not included.
> The documented way is {{RAW(Tom&Jerry)}}, which works. But percent-encoding
> the value is what a URL builder produces and what the Endpoint DSL produces
> itself.
> h3. Reproduction
> On main (origin/main 374c04877418):
> * New {{URISupportTest}} cases: {{normalizeUri("log:foo?marker=a%26b")}}
> gives {{log://foo?b=&marker=a}}, and {{parseParameters(new
> URI("log:foo?marker=a%26b&showAll=true"))}} gives {{marker=a}} plus {{b=}}.
> * New {{EndpointUriEncodedAmpersandTest}} (camel-core):
> {{context.getEndpoint("log:foo?marker=Tom%26Jerry")}} throws
> {{ResolveEndpointFailedException}}.
> * Both fail on main in 2 runs. A small program with the Endpoint DSL
> ({{log("foo").marker("Tom&Jerry").resolve(context)}}) fails with main's
> camel-util, and gets {{Tom&Jerry}} with the fix.
> h3. Proposed fix
> Split before decoding the {{&}}: {{parseParameters}} and the complex
> normalizer decode the raw query like {{URI.getQuery()}}, except that {{%26}}
> becomes a private marker character. They parse it with the same
> {{parseQuery}} as before, then turn the marker back into {{&}} in the keys
> and values. A query without {{%26}} takes exactly the old code path. All
> other escapes, {{+}}, {{RAW(...)}} values and the double decoding of {{%2B}}
> that CAMEL-25190 leaves for Camel 5 behave as before. {{prepareQuery(URI)}}
> (public) is unchanged.
> A differential run over 300000 generated endpoint URIs, main vs fix, compared
> {{normalizeUri}}, {{parseParameters}} of the URI and {{parseParameters}} of
> the normalized URI. 233864 were the same. Every one that differs has {{%26}}
> in the URI or in its normalized form. Three of them are malformed {{RAW(}}
> values without the closing bracket, where the normalizer already made the
> {{&}} part of the value.
> A Lean 4 model ({{proofs/CamelLean/R18EncodedAmpersand.lean}}) states the
> query as literal characters and percent escapes.
> {{cex_main_splits_encoded_amp}} computes main's two parameters for
> {{marker=a%26b}}. {{fix_eq_spec}} proves that for every query the fix splits
> only at a literal {{&}} (and otherwise decodes and splits key and value as
> main). {{fix_eq_main_without_encoded_amp}} proves that for every query
> without {{%26}} the fix gives main's result. RAW values and the decoding the
> scanner does after splitting are outside the model.
> Not in scope: the un-encoded form the Endpoint DSL builds for {{toD}}
> ({{getRawUri()}}: {{log://foo?marker=Tom&Jerry}}). That can only be fixed in
> the DSL, by adding {{&}} to the characters that
> {{AbstractEndpointBuilder.wrapRawIfNeeded}} wraps in {{RAW()}} (as
> CAMEL-24253 did for {{+}} and {{%}}).
> Affected: main and the 4.x releases. {{prepareQuery}} is the same in 4.14.0,
> 4.18.3 and 4.22.1. For the Endpoint DSL since 4.14.0 (CAMEL-22293).
> Duplicate check (2026-10-06): JIRA text "normalizeUri" (21 issues, among them
> CAMEL-25345, CAMEL-25190, CAMEL-25188, CAMEL-24187), "ampersand" (CAMEL-6977
> from 2013: {{authPassword=4%26Xy%25}} failed, answered with a pointer to
> RAW), Endpoint DSL encoding (CAMEL-24253, CAMEL-15015). None covers {{%26}}.
> GitHub pull requests: none.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)