Skip to content

WW-5688 Resolve id-bearing REST URIs into the root namespace when declared - #1862

Open
lukaszlenart wants to merge 1 commit into
mainfrom
WW-5688-rest-root-namespace
Open

WW-5688 Resolve id-bearing REST URIs into the root namespace when declared#1862
lukaszlenart wants to merge 1 commit into
mainfrom
WW-5688-rest-root-namespace

Conversation

@lukaszlenart

Copy link
Copy Markdown
Member

Fixes WW-5688, split out of the 2008 umbrella WW-2820 (originally reported by Alvin Singh). Of the five claims bundled there, this was the only one that still reproduced; the other four are dispositioned in a comment on that ticket, which is now closed.

The bug

RestActionMapper mapped a URI carrying an id into the default namespace, while mapping the same action without an id into /. Because RuntimeConfiguration.getActionConfig() only fails over from / to "" and never the other way round, an action declared in a package with namespace="/" resolved for index but 404'd for show, update and destroy:

Request namespace from the mapper resolved before
GET /dog / yes
GET /dog/1 (empty) no - 404

The fix

DefaultActionMapper has handled this since WW-2461 (June 2008) via a rootAvailable check — three months before WW-2820 reported the REST symptom. That fix was never ported to the copy of parseNameAndNamespace() the REST plugin had forked earlier. This PR ports it verbatim, including the ordering that computes the action name while the namespace is still empty, since the name is a substring relative to it.

Blast radius

Deliberately narrow:

  • The promotion fires only when a package explicitly declares namespace="/" and nothing more specific matched. Convention derives "" or /sub and never /, so it cannot trigger this on its own — the bundled rest-showcase is unaffected.
  • Because a / lookup already falls back to "", the set of resolvable actions after the change is a strict superset of the previous one. Nothing that resolved before stops resolving.
  • No change to core, and no new configuration surface.

Tests

  • RestActionMapperRootNamespaceTest (new) resolves all the way to the ActionConfig rather than stopping at the mapping, because the reported symptom is a 404. Confirmed RED before the fix: show/update/destroy failed while index and id-extraction passed, so the tests discriminate exactly this defect.
  • RestActionMapperTest.testParseNameAndNamespaceWithRootPackage covers the mapper level, including that a longer declared namespace still outranks the root. The pre-existing testParseNameAndNamespace pins the no-root-package direction, which is unchanged.

Full rest plugin suite (124 tests) and core's mapper tests (82 tests) pass.

Not a security fix

Verified before opening: this makes actions less reachable rather than more, and aligning /dog/1 with what /dog already resolves to exposes no surface the /dog path does not already expose.

Backporting to support/struts-6-x-x is deliberately left as a separate decision — it is a behaviour change on a maintenance line.

🤖 Generated with Claude Code

…en declared

RestActionMapper mapped a URI carrying an id into the default namespace while
mapping the same action without an id into "/". Since the configuration only
fails over from "/" to "" and never the other way round, an action declared in
a package with namespace="/" resolved for index but 404'd for show, update and
destroy.

DefaultActionMapper already handles this: WW-2461 added a rootAvailable check
in June 2008, three months before WW-2820 reported the REST symptom, but the
fix was never ported to the mapper the REST plugin had forked earlier. Port it,
keeping the ordering that computes the action name while the namespace is still
empty, since the name is relative to it.

The promotion only fires when a package explicitly declares namespace="/" and
nothing more specific matched. Convention derives "" or "/sub" and never "/",
so applications that do not opt in are unaffected, and because a "/" lookup
already falls back to "", the set of resolvable actions is a superset of the
previous one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant