pathutil

package
v1.59.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 1, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package pathutil provides reference building, escaping, and path sanitization utilities for OpenAPI document traversal.

Reference Builders

The package also provides functions for building JSON Pointer references to OpenAPI components:

ref := pathutil.SchemaRef("Pet")      // "#/components/schemas/Pet"
ref := pathutil.DefinitionRef("Pet")  // "#/definitions/Pet"

These use simple string concatenation which Go optimizes well for two operands, avoiding the overhead of fmt.Sprintf.

Version-aware helpers handle OAS 2.0 vs 3.x differences:

ref := pathutil.ParameterRef("limit", true)   // "#/parameters/limit" (OAS 2.0)
ref := pathutil.ParameterRef("limit", false)  // "#/components/parameters/limit" (OAS 3.x)

Reference Token Escaping

Component names are not always safe to drop into a JSON Pointer as-is: RFC 6901 gives "~" and "/" special meaning, so a component legitimately named "pet/summary" must be referenced as "#/definitions/pet~1summary". EscapeRefToken and UnescapeRefToken convert a single pointer token in each direction:

tok := pathutil.EscapeRefToken("pet/summary")   // "pet~1summary"
name := pathutil.UnescapeRefToken("pet~1summary") // "pet/summary"

Escape per token, never across a whole reference — escaping the full string would rewrite the "/" separators that give the pointer its structure.

Output Path Sanitization

SanitizeOutputPath validates and cleans output file paths for security. It rejects directory traversal ("..") and symlinks:

safe, err := pathutil.SanitizeOutputPath(userProvidedPath)
if err != nil {
    return err // path traversal or symlink detected
}

Index

Constants

View Source
const (
	RefPrefixDefinitions         = "#/definitions/"
	RefPrefixParameters          = "#/parameters/"
	RefPrefixResponses           = "#/responses/"
	RefPrefixSecurityDefinitions = "#/securityDefinitions/"
)

OAS 2.0 reference prefixes

View Source
const (
	RefPrefixSchemas         = "#/components/schemas/"
	RefPrefixParameters3     = "#/components/parameters/"
	RefPrefixResponses3      = "#/components/responses/"
	RefPrefixExamples        = "#/components/examples/"
	RefPrefixRequestBodies   = "#/components/requestBodies/"
	RefPrefixHeaders         = "#/components/headers/"
	RefPrefixSecuritySchemes = "#/components/securitySchemes/"
	RefPrefixLinks           = "#/components/links/"
	RefPrefixCallbacks       = "#/components/callbacks/"
	RefPrefixPathItems       = "#/components/pathItems/"
)

OAS 3.x reference prefixes

Variables

View Source
var PathParamRegex = regexp.MustCompile(`\{([^}]+)\}`)

PathParamRegex matches path template parameters like {paramName}. It captures the parameter name inside the braces.

Functions

func CallbackRef

func CallbackRef(name string) string

CallbackRef builds "#/components/callbacks/{name}" (OAS 3.x only).

func CutRefPrefix added in v1.59.0

func CutRefPrefix(ref, prefix string) (rest string, ok bool)

CutRefPrefix strips a JSON Pointer prefix from a reference, tolerating a reference whose pointer separators are percent-encoded, and returns the remainder with its own escaping untouched.

Generators reach that shape by running a URL escaper over a whole pointer rather than over each token, so "#/components/schemas/Paged%5BPet%5D" arrives as "#%2Fcomponents%2Fschemas%2FPaged%255BPet%255D". Rare, but a reference spelled that way denotes exactly the same component as the raw form and has to resolve to it.

prefix is matched one decoded byte at a time rather than against a wholesale url.PathUnescape of ref, because a wholesale decode would also decode the token that follows. That token has to reach DecodeRefToken still escaped for the exact-then-decoded lookup order to mean anything: decoding twice turns a component genuinely named "Paged%5BPet%5D" into "Paged[Pet]" and stops it matching itself. Keeping the decode confined to the prefix leaves DecodeRefToken the single place a name's escaping is reversed.

The prefix returned to the caller is the raw one it passed in, never the spelling ref used, so a decoded reference lands on the same key as a raw one.

func DecodeRefToken added in v1.58.0

func DecodeRefToken(token string) string

DecodeRefToken reverses both escaping conventions a reference token may carry, recovering the component name it denotes.

Documents are inconsistent here. RFC 6901 asks for "~1" and "~0", but code generators commonly percent-encode instead — and often encode only what their URL escaper considers unsafe, so "[" becomes "%5B" while "/" is left raw. A token like "Paged%5Bexample.com/pkg.Pet%5D" is therefore in neither convention, and no single unescaper recovers it.

Percent-decoding runs first so a percent-encoded tilde ("%7E1") is still recognized as a JSON Pointer escape afterwards. An invalid percent sequence leaves the token untouched rather than failing: a token that cannot be decoded is already the only form it has.

Decoding is lossy, so prefer the undecoded token when it already matches: a component genuinely named "Foo%20Bar" decodes to "Foo Bar" and would otherwise stop matching itself. Callers should try the exact spelling first and fall back to this.

func DefinitionRef

func DefinitionRef(name string) string

DefinitionRef builds "#/definitions/{name}" (OAS 2.0).

func EscapeRefToken added in v1.54.0

func EscapeRefToken(name string) string

EscapeRefToken escapes a component name for use as a single JSON Pointer token, per RFC 6901: "~" becomes "~0" and "/" becomes "~1".

Order matters — "~" must be escaped first, or the "~" introduced by escaping "/" would itself be escaped and produce "~01".

OAS 2.0 places no charset constraint on the keys of the root-level parameters, definitions, and responses objects, so a name containing either character is legitimate and must be escaped for a document to reference it. Building a reference by raw concatenation instead produces a pointer that names a different location and therefore never matches.

func ExampleRef

func ExampleRef(name string) string

ExampleRef builds "#/components/examples/{name}" (OAS 3.x only).

func HeaderRef

func HeaderRef(name string) string

HeaderRef builds "#/components/headers/{name}" (OAS 3.x only).

func LinkRef

func LinkRef(name string) string

LinkRef builds "#/components/links/{name}" (OAS 3.x only).

func ParameterRef

func ParameterRef(name string, oas2 bool) string

ParameterRef builds the appropriate parameter ref. If oas2 is true, returns "#/parameters/{name}", otherwise "#/components/parameters/{name}".

func PathItemRef

func PathItemRef(name string) string

PathItemRef builds "#/components/pathItems/{name}" (OAS 3.1+ only).

func RequestBodyRef

func RequestBodyRef(name string) string

RequestBodyRef builds "#/components/requestBodies/{name}" (OAS 3.x only).

func ResponseRef

func ResponseRef(name string, oas2 bool) string

ResponseRef builds the appropriate response ref. If oas2 is true, returns "#/responses/{name}", otherwise "#/components/responses/{name}".

func SanitizeOutputPath added in v1.52.0

func SanitizeOutputPath(path string) (string, error)

SanitizeOutputPath validates and cleans an output file path. It resolves ".." components via filepath.Clean + filepath.Abs and rejects paths that resolve to symlinks. New files in existing directories are accepted. Returns the cleaned absolute path.

func SchemaRef

func SchemaRef(name string) string

SchemaRef builds "#/components/schemas/{name}" (OAS 3.x).

func SecuritySchemeRef

func SecuritySchemeRef(name string, oas2 bool) string

SecuritySchemeRef builds the appropriate security scheme ref. If oas2 is true, returns "#/securityDefinitions/{name}", otherwise "#/components/securitySchemes/{name}".

func UnescapeRefToken added in v1.54.0

func UnescapeRefToken(token string) string

UnescapeRefToken reverses EscapeRefToken, recovering a component name from a single JSON Pointer token.

Use it anywhere a reference is split back into a name — renaming, pruning, or resolving a ref to its definition — or names containing "/" or "~" are corrupted. Order is the inverse of escaping: "~1" must be unescaped before "~0", or the "~" recovered from "~0" could combine with a following "1".

Mirrors unescapeJSONPointer in the parser's resolver, which has always implemented this for reference resolution.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL