Skip to content

[ENG-4059] Resolve request fields the way applications read them - #304

Merged
patchstackdave merged 2 commits into
fix/request-decodingfrom
fix/request-field-shapes
Sep 29, 2026
Merged

patchstackdave merged 2 commits into
fix/request-decodingfrom
fix/request-field-shapes

Conversation

@patchstackdave

@patchstackdave patchstackdave commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #298 (request value decoding), which should merge first.

Makes a rule see a request field in the same form the application reads it, whichever parser produced the request, and reports when a value is too large to inspect in full.

  • Cookies. Pairs are split first, then their values are normalised the same way whether a framework already parsed them or they come from the Cookie header. Quoted values lose their quotes, and a name sent more than once keeps every value, so a rule inspects each one.
  • Bracketed field names. get.user.name also resolves user[name], and get.id also resolves id[]. The reverse works too, so a rule written in either spelling applies both to parsers that expand brackets and to parsers that keep them as literal keys. The request.* source follows the same rule.
  • Large structured values. Beyond the leaf walk's bound, the value is matched as serialised text, and the bound is reported as a container-cap skip through onSkip / coverage(). This applies to the request phase and, once per response, to the response phase. A decoding mutation that reaches its own node or depth bound on a structured value reports the same skip, so a value handed to a whole-value matcher past that bound is visible too.
  • internal_host. The host is also read from the shorter URL spellings a URL parser still resolves: http:/host, http:host, backslash forms, and tabs or leading control characters.

Synthetic tests cover each shape, including its fetch, Node and Express paths, with controls that must not match.

Validation: full suite with #298 (3,501 passed, 7 skipped), typecheck and build.

🤖 Generated with Claude Code

@coderbuds

coderbuds Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Well-commented and cohesive enhancements to request parsing and normalization.

🎯 Quality: 95% Elite · 📦 Size: Extra Large — strongly consider breaking this down

🛡️ Standards: Not checked — 631 lines changed, over your team's 400-line limit, and nothing checked before it was opened. Coding agents can call the assess-change-fit tool first, while a change this size is still cheap to split.

🤖 Authorship: Agent-written — Claude Code, going by its own attribution. Whether a person read it is unknown; coding agents can call the report-ai-usage tool to say.

📈 This month: Your 161st PR — above team average · Averaging Good

See how your team is trending →

@patchstackdave
patchstackdave force-pushed the fix/request-field-shapes branch from 7267294 to d01cc6f Compare September 28, 2026 14:46
@patchstackdave
patchstackdave changed the base branch from main to fix/request-decoding September 28, 2026 14:46
patchstackdave and others added 2 commits September 28, 2026 17:03
Cookie values are split before they are normalised, and normalised the
same way whether a framework parsed them or they come from the header.
Quoted values lose their quotes, and a repeated name keeps every value.

Field paths resolve in both spellings a form or query field can take:
nested (`user.name`, `id`) and bracketed (`user[name]`, `id[]`),
whichever parser produced the request.

A structured value too large for the leaf walk is matched as serialised
text beyond the walk's bound, and the bound is reported as a
`container-cap` coverage skip.

`internal_host` reads the host from the shorter URL spellings a URL
parser still resolves (`http:/host`, `http:host`, backslashes, tabs and
leading controls).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A decoding mutation applied to a structured value keeps any node past
its node or depth bound undecoded. That is now reported as the same
`container-cap` skip the leaf walk reports, so a value that reaches a
whole-value matcher past the bound is visible in `onSkip` and
`coverage()` instead of being matched undecoded without notice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@patchstackdave
patchstackdave force-pushed the fix/request-field-shapes branch from d01cc6f to 6bc268b Compare September 28, 2026 15:04
@patchstackdave
patchstackdave added this pull request to stack #318 September 29, 2026 08:03
@patchstackdave

Copy link
Copy Markdown
Contributor Author

/review

@patchstackdave
patchstackdave merged commit 2d26413 into main Sep 29, 2026
18 checks passed
@patchstackdave
patchstackdave deleted the fix/request-field-shapes branch September 29, 2026 09:11
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