allthingssecurity opened a new pull request, #27590:
URL: https://github.com/apache/camel/pull/27590

   # Description
   
   [CAMEL-25453](https://issues.apache.org/jira/browse/CAMEL-25453)
   
   `URISupport` decoded the query of an endpoint URI before it split it into 
options, so an encoded `&` (`%26`) separated two options. 
`log:foo?marker=Tom%26Jerry` normalized to `log://foo?Jerry=&marker=Tom`, and 
creating the endpoint failed with *There are 1 parameters that couldn't be set 
on the endpoint*. A lenient component such as `http` got the value cut at the 
`%26` plus an extra parameter. `log:foo?marker=%E2%82%AC%26` failed with 
*Trailing & marker found*.
   
   Both `parseParameters(URI)` (used by `DefaultComponent` to configure the 
endpoint) and the complex normalizer in `normalizeUri` took the query from 
`prepareQuery(URI)`, which is `URI.getQuery()`: every escape was already 
decoded when the `URIScanner` split at `&`. The scanner itself does not decode 
values, so the encoded `&` could not survive.
   
   The Endpoint DSL hits the same path. `AbstractEndpointBuilder.computeUri` 
encodes values with `createQueryString` (`&` becomes `%26`) and resolves the 
URI as already normalized, so `log("foo").marker("Tom&Jerry")` failed to 
resolve. CAMEL-24253 fixed the same double decoding for `+` and `%` by wrapping 
such values in `RAW()`. `&` was not covered.
   
   The fix: when the raw query contains `%26`, both places decode it like 
`URI.getQuery()` does, except that `%26` becomes a private marker character 
(U+FFFF, a noncharacter). They parse it with the same `parseQuery` as before, 
then turn the marker back into `&` in the keys and values. A query without 
`%26` (or one that contains the marker character itself) takes the old code 
path unchanged. `+`, the other escapes, `RAW(...)` values and the double 
decoding of `%2B` (left for Camel 5 by CAMEL-25190) behave as before. The 
public `prepareQuery(URI)` is unchanged.
   
   Evidence that nothing else changes: I compared main and this branch on 
300000 generated endpoint URIs (keys and values built from `%26`, `%25`, `%2B`, 
`+`, `%3D`, `=`, `%23`, `RAW(`, `)`, multi-byte escapes, placeholders, and so 
on; seven schemes). I compared `normalizeUri`, `parseParameters` of the URI and 
`parseParameters` of the normalized URI. 233864 were the same. All 66136 that 
differ have `%26` in the URI or in its normalized form. Three of them are 
malformed `RAW(` values without the closing bracket, where the normalizer had 
already made the `&` part of the value.
   
   Found and checked with a Lean 4 model of the query as literal characters and 
percent escapes (`proofs/CamelLean/R18EncodedAmpersand.lean`). 
`cex_main_splits_encoded_amp` gives main's two parameters for `marker=a%26b`. 
`fix_eq_spec` proves that the fix splits only at a literal `&`. 
`fix_eq_main_without_encoded_amp` proves that the fix equals main for every 
query without `%26`. RAW values are not modelled, and the fuzz run above covers 
them.
   
   Not in scope: the un-encoded URI that the Endpoint DSL builds for `toD` 
(`getRawUri()` gives `log://foo?marker=Tom&Jerry`). That can only be fixed in 
the DSL, by adding `&` to `AbstractEndpointBuilder.wrapRawIfNeeded`.
   
   Upgrade guide: a short entry under the 4.23 camel-core sections, since a URI 
with `%26` now configures the option instead of failing or splitting it.
   
   Tests:
   - `URISupportTest`: `testNormalizeEncodedAmpersand` (in a value, in a key, 
with other options, at the end of a multi-byte value, http, normalizing twice) 
and `testParseParametersEncodedAmpersand` (also: a `RAW` value, other escapes 
and a value with the marker character itself are parsed as before).
   - `EndpointUriEncodedAmpersandTest` (camel-core): 
`getEndpoint("log:foo?marker=Tom%26Jerry")` sets the marker and finds the same 
endpoint again. The same with other options, and with an already normalized URI 
as the Endpoint DSL resolves it.
   - Negative control: the new tests fail on main's `URISupport` (camel-util 2 
runs, camel-core 3 runs of 3 attempts).
   - Suites: camel-util 296 tests. The core reactor up to camel-core passes: 55 
modules, including camel-api, camel-support, camel-base, camel-base-engine, the 
core processor, model, reifier, engine and languages, the core components, and 
camel-core with 8073 tests. The one error, `ValidatorExternalResourceTest`, 
fetches an XSD from raw.githubusercontent.com and fails the same way on main in 
this environment. In an earlier run of an intermediate version, 
`FileConsumePollEnrichFileIdleEventTest` flaked once and passed on rerun. It 
passed in the final run.
   
   Relation to CAMEL-25345 (`camel-util-normalize-uri-idempotent`): both change 
`URISupport.normalizeUri` paths and the 4.23 upgrade guide, in different hunks. 
`git merge-tree` of the two branches is clean.
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for 
the change (usually before you start working on it).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
     (I built and tested the core modules with the formatter and import-sort 
plugins. No generated files change. I did not run the full root build.)
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
     This PR was prepared with Claude Code (Claude Opus 5.5). The commit 
carries a `Co-Authored-By` trailer.
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to