Skip to content

fix: resolve open validation issues (#313 #316 #319 #320 #321 #322 #323) - #326

Merged
daveshanley merged 1 commit into
mainfrom
claude/libopenapi-validator-triage-7b7eb0
Sep 29, 2026
Merged

daveshanley merged 1 commit into
mainfrom
claude/libopenapi-validator-triage-7b7eb0

Conversation

@daveshanley

Copy link
Copy Markdown
Member

Fixes the open, non-feature issues from the issue triage, plus several crashes found along the way.

Changes

  • Routing (#313). Path-only matching strips the base path of a server whose host has a variable (https://{host}/api/v1), restoring the Added secondary parsing if the initial base path parsing fails; the s… #68 fallback. When several servers prefix the request, each is tried in document order. Path parameters are read from the path the router matched, which fixes a panic with strict server matching and a variable in the base path.
  • Media ranges (#316). Request bodies, response bodies and request defaults share one matcher that picks the most specific key: exact, type/*+suffix, type/*, */subtype, then */*. It no longer panics on a Content-Type without a slash.
  • Response headers (#321). Every header that is present is checked against its schema; required only controls presence. Values are read the way the schema allows (each declared type, then JSON, then the raw string). A default response without content now matches, and a declared Content-Type header is ignored, as OpenAPI requires.
  • Integer parameters (#319, #320). Whole numbers written as 1.0 or 1e3 are accepted as integers, and integer enums compare numerically. Header and cookie numbers are schema-validated, so minimum, maximum and format apply. WithFormatAssertions() enforces the OpenAPI int32 and int64 formats; a WithCustomFormat of the same name still wins. Parameter schemas compile with their document's OpenAPI version.
  • Path templates with a fragment. A template like /pages/{id}#section ignores its fragment when the request has none, as the router does. Before this, /pages/5 was reported as missing id.
  • Document node mutation (#322). Document-owned yaml nodes are copied before they are marshalled, because the go-yaml fork strips tags from the nodes it encodes (Marshal strips all resolvable tags in place yaml/go-yaml#371).
  • Go 1.27 (#323). Tests no longer rely on json.Marshal rejecting map[interface{}]interface{}, which Go 1.27 accepts.

Crashes fixed

ValidateHttpRequest runs validators in goroutines, so each of these took down the whole process:

  • a Content-Type of application (no slash) in request body validation
  • NaN or Inf in a number query or path parameter
  • an empty matrix value (/things/;matrix=)
  • strict server matching with a variable in the server's base path

Behaviour changes

  • Optional response headers are validated when present. ExampleNewValidator_responseHeaderNotRequired is updated.
  • Response header values are no longer URL-decoded, so a+b stays a+b.
  • Header and cookie numeric constraints are now enforced.
  • 1.0 is accepted as an integer.
  • Path-only routing tries every server whose base path prefixes the request, in document order.
  • router.Route gains a public RequestPath field.

Verification

  • Full suite passes on Go 1.26.4 and Go 1.27.0 (main fails TestNormalizeJSON_ReturnsMarshalError on 1.27), and with -race.
  • golangci-lint v2.12.1: 0 issues.
  • Every changed line is covered by tests (353 of 353); project coverage goes from 98.29% to 98.37%.

The media-range matcher builds on #318 by @adrienyhuel, who is credited as co-author.

Fixes #313, fixes #316, fixes #319, fixes #320, fixes #321, fixes #322, fixes #323

🤖 Generated with Claude Code

- router/paths: strip server base paths when the host has a variable, try
  every server whose base path prefixes the request, and read path
  parameters from the path the router matched (fixes a panic with strict
  server matching and a variable in the base path) (#313)
- requests/responses: share one media-range matcher that prefers the most
  specific key and no longer panics on a Content-Type without a slash (#316)
- responses: validate every response header that is present, by the
  readings its schema allows; match a default response without content;
  ignore Content-Type header declarations (#321)
- parameters: accept whole numbers written as 1.0 or 1e3 for integers,
  compare integer enums numerically, schema-validate header and cookie
  numbers, reject NaN/Inf and empty matrix values (both panicked), and
  compile parameter schemas with their document's OpenAPI version
  (#319, #320)
- parameters: ignore a path template's #fragment when the request has
  none, as the router does, instead of reporting the parameter missing
- helpers: enforce OpenAPI int32/int64 formats with WithFormatAssertions (#320)
- schema_validation: never marshal document-owned yaml nodes in place (#322)
- tests: stop relying on json.Marshal rejecting map[interface{}]interface{},
  which Go 1.27 accepts (#323)

Fixes #313, fixes #316, fixes #319, fixes #320, fixes #321, fixes #322,
fixes #323

Co-authored-by: adrienyhuel <14916484+adrienyhuel@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.36%. Comparing base (302f295) to head (56a3f7f).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #326      +/-   ##
==========================================
+ Coverage   98.28%   98.36%   +0.08%     
==========================================
  Files          75       79       +4     
  Lines        9266     9433     +167     
==========================================
+ Hits         9107     9279     +172     
+ Misses        132      129       -3     
+ Partials       27       25       -2     
Flag Coverage Δ
unittests 98.36% <100.00%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@daveshanley
daveshanley merged commit f140310 into main Sep 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment