Skip to content

feat: inject a custom document loader into schema/spec validation#272

Merged
fredbi merged 1 commit into
go-openapi:masterfrom
fredbi:feat/confined-ref-loading
Jul 21, 2026
Merged

feat: inject a custom document loader into schema/spec validation#272
fredbi merged 1 commit into
go-openapi:masterfrom
fredbi:feat/confined-ref-loading

Conversation

@fredbi

@fredbi fredbi commented Jul 20, 2026

Copy link
Copy Markdown
Member

Building a schema validator expands the schema's $ref, and validating a specification resolves and expands $ref (schemas, parameters, responses, and the whole-spec expansion). All of these resolved documents through the spec package's global loader, with no way for a caller to supply their own.

Add WithPathLoader, an option-aware loader on SchemaValidatorOptions, consumed by every path that loads documents during validation:

  • newSchemaValidator uses spec.ExpandSchemaWithOptions (instead of the default-settings ExpandSchema).
  • resolveParam / expandResponseRef use spec.ExpandParameterWithOptions and spec.ExpandResponseWithOptions.
  • SpecValidator.resolveRef passes the loader through spec.ResolveRefWithBase.
  • validateReferencesValid passes it to loads.Document.Expanded (no-op when unset: loads falls back to the document's own loader).
  • NewSpecValidator and the package-level Spec now accept ...Option, applied to the internal schema options after the built-in defaults, so a caller can inject the loader into spec validation. Backward compatible: existing two-argument calls are unaffected.

The injected loader may carry any go-openapi/swag/loading options — a custom HTTP client or timeout, authentication or custom headers, an embedded or rooted file system, and so on. One important use is confining loading of untrusted input (loading.WithRoot to confine local reads, loading.WithHTTPClient to restrict remote fetches, or a restricted loader from go-openapi/loads), which closes the arbitrary-file-read / SSRF surface that the unsandboxed default otherwise exposes. Left unset, behavior is unchanged.

Bumps spec to v0.22.9 (for the option-aware expanders), analysis to v0.25.5, loads to v0.25.0 and swag to v0.27.3.

Change type

Please select: 🆕 New feature or enhancement|🔧 Bug fix'|📃 Documentation update

Short description

Fixes

Full description

Checklist

  • I have signed all my commits with my name and email (see DCO. This does not require a PGP-signed commit
  • I have rebased and squashed my work, so only one commit remains
  • I have added tests to cover my changes.
  • I have properly enriched go doc comments in code.
  • I have properly documented any breaking change.

Building a schema validator expands the schema's $ref, and validating a
specification resolves and expands $ref (schemas, parameters, responses, and the
whole-spec expansion). All of these resolved documents through the spec package's
global loader, with no way for a caller to supply their own.

Add WithPathLoader, an option-aware loader on SchemaValidatorOptions, consumed by
every path that loads documents during validation:

  - newSchemaValidator uses spec.ExpandSchemaWithOptions (instead of the
    default-settings ExpandSchema).
  - resolveParam / expandResponseRef use spec.ExpandParameterWithOptions and
    spec.ExpandResponseWithOptions.
  - SpecValidator.resolveRef passes the loader through spec.ResolveRefWithBase.
  - validateReferencesValid passes it to loads.Document.Expanded (no-op when unset:
    loads falls back to the document's own loader).
  - NewSpecValidator and the package-level Spec now accept ...Option, applied to
    the internal schema options after the built-in defaults, so a caller can
    inject the loader into spec validation. Backward compatible: existing
    two-argument calls are unaffected.

The injected loader may carry any go-openapi/swag/loading options — a custom HTTP
client or timeout, authentication or custom headers, an embedded or rooted file
system, and so on. One important use is confining loading of untrusted input
(loading.WithRoot to confine local reads, loading.WithHTTPClient to restrict
remote fetches, or a restricted loader from go-openapi/loads), which closes the
arbitrary-file-read / SSRF surface that the unsandboxed default otherwise exposes.
Left unset, behavior is unchanged.

Bumps spec to v0.22.9 (for the option-aware expanders), analysis to v0.25.5,
loads to v0.25.0 and swag to v0.27.3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
@fredbi
fredbi force-pushed the feat/confined-ref-loading branch from 0f0d429 to 58f6939 Compare July 21, 2026 05:35
@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.37%. Comparing base (cbf963a) to head (58f6939).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #272      +/-   ##
==========================================
+ Coverage   92.35%   92.37%   +0.01%     
==========================================
  Files          24       24              
  Lines        3272     3280       +8     
==========================================
+ Hits         3022     3030       +8     
  Misses        165      165              
  Partials       85       85              

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

@fredbi
fredbi merged commit 9b81767 into go-openapi:master Jul 21, 2026
21 checks passed
@fredbi
fredbi deleted the feat/confined-ref-loading branch July 21, 2026 05:45
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