Repository navigation
Tags: oapi-codegen/oapi-codegen
Tags
Quote or validate every spec string that reaches generated Go source … …(2.8.x backport) (#2626) * Quote or validate every spec string that reaches generated Go source (2.8.x) Hand port of the main change to the 2.8.x templates and code: the two initiator templates and both Echo register templates carry the sinks that main has in one file each, strict-fiber-v3.tmpl has a raw content-type literal that main's unified Fiber template already quotes, and the discriminator literal helper does not exist here, so that item is dropped. - webhook-initiator.tmpl and callback-initiator.tmpl emitted the request body's content type as "{{.ContentType}}", and strict-fiber-v3.tmpl did the same in its multi-body content-type match; they now go through toGoString like the client's does. MIME parameters may legitimately contain quoted strings, which also used to produce code that did not compile. - echo/echo-register.tmpl and echo/v5/echo-register.tmpl emitted the raw operationId as the OperationMiddlewares key inside literal quotes; they now go through toGoString. ValidateSpec additionally rejects control characters in an operationId. - A non-string enum is emitted unquoted, and its values were whatever the spec wrote. GenerateEnums now requires each such value to be a number or boolean literal and reports the offending value otherwise. - toStringArray joined security scopes with `","`: a scope ending in a backslash escaped the quote the joiner supplied and the next scope became code. Each element is now quoted on its own. - Response keys are copied into type names and, for the client, into `rsp.StatusCode == <key>`; they were never checked. ValidateSpec now requires a three-digit code, a range such as 2XX, or default. - Component names (schemas, parameters, request bodies, responses, headers, callbacks, security schemes) reach single-line doc comments verbatim, so a newline ended the comment; ValidateSpec rejects control characters in them. Quotes stay allowed, since the names become identifiers only after sanitization. - A response header's style is copied into a string literal by the strict templates like a parameter's; it is now checked the same way. - The server-urls generator uses x-go-name, variable names, undeclared {placeholder} names and enum values as identifiers without sanitizing them. A new ValidateServerURLs, run only when server URLs are generated so other specs are unaffected, requires each to be a Go identifier (enum values: identifier characters, since they are appended to the type name). Generated fixtures are unchanged: every valid value renders byte-for-byte as before. Each item has a regression test; the end-to-end ones generate from a crafted document and check that the payload stays inside a string literal or is rejected with a clear error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Check only the server variables the URL uses Review feedback on #2625. ValidateServerURLs checked every declared variable, but the generator only emits code for variables whose {name} placeholder appears in the URL, so a server with an unused hyphenated variable, or an unused enum value such as us-east, was refused although it generated fine before. Limit the name and enum-value checks to UsedVariables, keeping the separate check for undeclared placeholders, and cover the unused case in the test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Add missing case to validation (#2493) `checkExtensions` in `validate_spec.go` validated `x-go-name`, `x-go-type-name`, `x-go-type`, and `x-oapi-codegen-extra-tags`, but had no case for `x-go-type-import`. This adds validation for both fields of that extension: - `name`: must be empty, `"."` (dot-import), or a valid Go identifier; handled by a new `checkGoImportName` method - `path`: must not contain control characters; handled by a new `checkGoImportPath` method (the path is emitted with `%q` so control characters would be escaped anyway, but we reject obviously malformed inputs early) Also adds `validate_spec_test.go` with tests covering valid inputs, invalid `name` and `path` values, case-insensitive key matching (mirroring `ParseGoImportExtension`), and regression coverage for the pre-existing extension checks. Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Add sort-handler-registrations flag to opt out of spec-order registra… …tion (#2477) PR #2465 (issue #1887) changed generated servers to register route handlers in spec-declaration order, so that routers which match in registration order (Fiber, Gorilla/mux) can disambiguate overlapping paths by ordering them in the spec. This makes that behavior opt-out: the new sort-handler-registrations compatibility flag restores the historical lexicographic (by path, then method) registration order for users who relied on it. The dispatch is a single seam -- operationsInRegistrationOrder picks sortOperationsLexicographically when the flag is set, otherwise the existing sortOperationsBySpecOrder -- and all nine GenerateXServer functions route through it. The lexicographic sort reproduces the historical gather order (SortedMapKeys over paths then methods), so with the flag unset the default output is unchanged. Adds TestSortHandlerRegistrations and documents the flag in configuration-schema.json. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make sure to escape user strings (#2433) Spec-derived paths and string enum values were interpolated into generated Go source without escaping, so a value containing a quote could produce malformed output. Route paths in the server registration templates and string enum constants are now emitted through strconv.Quote (the existing toGoString helper) so they are always valid, properly-escaped Go string literals. Generated output is unchanged for normal specs. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Improve string escaping and add tests (#2396) Tighten how server URL values are emitted in the server-urls template so that spec-supplied text is always serialized into a proper Go context: - Route server descriptions and URLs through stripNewLines when they are written into generated // comments, so a multi-line value stays on the comment line instead of spilling into following lines. - Emit server URL and variable-default values via toGoString (now backed by strconv.Quote) instead of hand-wrapping them in quotes, so quotes, backslashes, and newlines are escaped correctly. - Harden StringToGoString to use strconv.Quote; the previous version only escaped double quotes and mishandled backslashes. This also tidies up the content-type literals that already used it. - Extend stripNewLines to drop carriage returns as well as newlines. Add regression tests covering the server-urls rendering and the StringToGoString escaping, and confirm `make generate` produces no changes to committed output. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
refactor(codegen): better Swagger compression, modern naming (#1909) * refactor(codegen): better Swagger compression * test(compatibility): Regenerate test spec * Add GetSpec/GetSpecJSON; revert const-concat embed format Three follow-ups to PR #1909, all in `pkg/codegen/templates/inline.tmpl` (plus the regenerated `*.gen.go` files and migrated callers): 1. Revert the embedded spec back to `var swaggerSpec = []string{...}`. PR #1909 replaced the historical slice-of-chunks form with a single `const swaggerSpec = "" + "chunk" + "chunk" + ...`. With thousands of 80-char chunks (large APIs produce them) the Go compiler folds the chained `+` at compile time, and that fold is materially slower than parsing a slice literal. `decodeSpec` now joins the slice via `strings.Join` before base64-decoding; flate compression, base64 encoding, the 80-char chunk size, the lazy `decodeSpecCached` / `rawSpec` pipeline, and `PathToRawSpec` all stay exactly as PR #1909 landed them. 2. Add `GetSpec() (*openapi3.T, error)` as the canonical accessor, and demote `GetSwagger()` to a `// Deprecated:` thin wrapper. The kin-openapi spec type was renamed from `openapi3.Swagger` to `openapi3.T` years ago; `GetSwagger`'s name is a stale relic. `GetSpec` carries the body that `GetSwagger` had, and `GetSwagger` becomes a one-line `return GetSpec()` retained for backwards compatibility. External callers still upgrading to a newer version of oapi-codegen will see the `// Deprecated:` hint surfaced by gopls/godoc; in-tree callers across `examples/` and `internal/test/` are migrated to `GetSpec()` because the repo's lint rule rejects calls into deprecated functions and would otherwise block CI. 3. Add `GetSpecJSON() ([]byte, error)` returning the embedded JSON. Decompressed, base64-decoded, but not unmarshaled into `*openapi3.T`. A one-line wrapper around the existing `rawSpec()` cache, so repeated calls don't re-decompress. This fills a long-standing gap: callers who want to operate on the raw OpenAPI document (re-marshal to YAML, hand to a different parser, run an overlay, dump to disk) previously had to either invoke `openapi3.T.MarshalJSON` after `GetSpec` or hand-roll base64+flate decode. Migrated callers (mechanical; no logic changes): - 7 user-side example files under `examples/` (petstore variants for each framework, authenticated-api echo + stdhttp). - 12 test files under `examples/petstore-expanded/*/petstore_test.go`, `internal/test/externalref/imports_test.go`, `internal/test/issues/issue1825/overlay_test.go`, `internal/test/compatibility/preserve-original-operation-id-casing-in-embedded-spec/spec_test.go`. New test: - `examples/petstore-expanded/chi/petstore_test.go::TestSpecAccess` covers `GetSpec` and `GetSpecJSON` end-to-end (asserts the bytes are valid JSON and the parsed spec has a non-empty `OpenAPI` version field). `GetSwagger` is intentionally not exercised — its body is `return GetSpec()` and the lint rule blocks an in-tree call. If we later want regression coverage for the wrapper specifically, one test annotated with `//nolint:staticcheck // SA1019` would do it. Verification: - `make generate` is idempotent; spot-checking `examples/petstore-expanded/chi/api/petstore.gen.go` confirms the slice form, the three new accessors, and the `// Deprecated:` marker on `GetSwagger`. - `make test` passes (exit 0) across the root module and all eight child modules. - `make lint` reports `0 issues.` across the same nine modules — no remaining in-tree calls into the deprecated wrapper. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Marcin Romaszewicz <marcinr@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
build: relax patch version pinning on `go` directive Originally added in f77bd7b, we wanted to pin the version to ensure that we were targeting the latest version of Go 1.21. However, there's no real value here, and as noted in [0] it can be causing issues for some users. There's nothing explicitly in Go 1.21.x that we need to pin to, just that we need support for Go 1.21, so we can use Speakeasy's `openapi-overlay` library. Therefore we can relax the patch-version requirement, which will alleviate issues for consumers. This makes sure that we have _at a minimum_ a version of Go 1.21, and makes `go mod tidy` happy. [0]: osbuild/image-builder#1352
PreviousNext