diff options
Diffstat (limited to 'vendor/github.com/go-openapi/validate')
32 files changed, 0 insertions, 8135 deletions
diff --git a/vendor/github.com/go-openapi/validate/.editorconfig b/vendor/github.com/go-openapi/validate/.editorconfig deleted file mode 100644 index 3152da69a..000000000 --- a/vendor/github.com/go-openapi/validate/.editorconfig +++ /dev/null @@ -1,26 +0,0 @@ -# top-most EditorConfig file -root = true - -# Unix-style newlines with a newline ending every file -[*] -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true - -# Set default charset -[*.{js,py,go,scala,rb,java,html,css,less,sass,md}] -charset = utf-8 - -# Tab indentation (no size specified) -[*.go] -indent_style = tab - -[*.md] -trim_trailing_whitespace = false - -# Matches the exact files either package.json or .travis.yml -[{package.json,.travis.yml}] -indent_style = space -indent_size = 2 diff --git a/vendor/github.com/go-openapi/validate/.gitattributes b/vendor/github.com/go-openapi/validate/.gitattributes deleted file mode 100644 index 49ad52766..000000000 --- a/vendor/github.com/go-openapi/validate/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# gofmt always uses LF, whereas Git uses CRLF on Windows. -*.go text eol=lf diff --git a/vendor/github.com/go-openapi/validate/.gitignore b/vendor/github.com/go-openapi/validate/.gitignore deleted file mode 100644 index fea8b84ec..000000000 --- a/vendor/github.com/go-openapi/validate/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -secrets.yml -coverage.out -*.cov -*.out -playground diff --git a/vendor/github.com/go-openapi/validate/.golangci.yml b/vendor/github.com/go-openapi/validate/.golangci.yml deleted file mode 100644 index 22f8d21cc..000000000 --- a/vendor/github.com/go-openapi/validate/.golangci.yml +++ /dev/null @@ -1,61 +0,0 @@ -linters-settings: - govet: - check-shadowing: true - golint: - min-confidence: 0 - gocyclo: - min-complexity: 45 - maligned: - suggest-new: true - dupl: - threshold: 200 - goconst: - min-len: 2 - min-occurrences: 3 - -linters: - enable-all: true - disable: - - maligned - - unparam - - lll - - gochecknoinits - - gochecknoglobals - - funlen - - godox - - gocognit - - whitespace - - wsl - - wrapcheck - - testpackage - - nlreturn - - gomnd - - exhaustivestruct - - goerr113 - - errorlint - - nestif - - godot - - gofumpt - - paralleltest - - tparallel - - thelper - - ifshort - - exhaustruct - - varnamelen - - gci - - depguard - - errchkjson - - inamedparam - - nonamedreturns - - musttag - - ireturn - - forcetypeassert - - cyclop - # deprecated linters - - deadcode - - interfacer - - scopelint - - varcheck - - structcheck - - golint - - nosnakecase diff --git a/vendor/github.com/go-openapi/validate/BENCHMARK.md b/vendor/github.com/go-openapi/validate/BENCHMARK.md deleted file mode 100644 index 79cf6a077..000000000 --- a/vendor/github.com/go-openapi/validate/BENCHMARK.md +++ /dev/null @@ -1,31 +0,0 @@ -# Benchmark - -Validating the Kubernetes Swagger API - -## v0.22.6: 60,000,000 allocs -``` -goos: linux -goarch: amd64 -pkg: github.com/go-openapi/validate -cpu: AMD Ryzen 7 5800X 8-Core Processor -Benchmark_KubernetesSpec/validating_kubernetes_API-16 1 8549863982 ns/op 7067424936 B/op 59583275 allocs/op -``` - -## After refact PR: minor but noticable improvements: 25,000,000 allocs -``` -go test -bench Spec -goos: linux -goarch: amd64 -pkg: github.com/go-openapi/validate -cpu: AMD Ryzen 7 5800X 8-Core Processor -Benchmark_KubernetesSpec/validating_kubernetes_API-16 1 4064535557 ns/op 3379715592 B/op 25320330 allocs/op -``` - -## After reduce GC pressure PR: 17,000,000 allocs -``` -goos: linux -goarch: amd64 -pkg: github.com/go-openapi/validate -cpu: AMD Ryzen 7 5800X 8-Core Processor -Benchmark_KubernetesSpec/validating_kubernetes_API-16 1 3758414145 ns/op 2593881496 B/op 17111373 allocs/op -``` diff --git a/vendor/github.com/go-openapi/validate/CODE_OF_CONDUCT.md b/vendor/github.com/go-openapi/validate/CODE_OF_CONDUCT.md deleted file mode 100644 index 9322b065e..000000000 --- a/vendor/github.com/go-openapi/validate/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at ivan+abuse@flanders.co.nz. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/go-openapi/validate/LICENSE b/vendor/github.com/go-openapi/validate/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/vendor/github.com/go-openapi/validate/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/go-openapi/validate/README.md b/vendor/github.com/go-openapi/validate/README.md deleted file mode 100644 index e8e1bb218..000000000 --- a/vendor/github.com/go-openapi/validate/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Validation helpers [](https://github.com/go-openapi/validate/actions?query=workflow%3A"go+test") [](https://codecov.io/gh/go-openapi/validate) - -[](https://slackin.goswagger.io) -[](https://raw.githubusercontent.com/go-openapi/validate/master/LICENSE) -[](https://pkg.go.dev/github.com/go-openapi/validate) -[](https://goreportcard.com/report/github.com/go-openapi/validate) - -This package provides helpers to validate Swagger 2.0. specification (aka OpenAPI 2.0). - -Reference can be found here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md. - -## What's inside? - -* A validator for Swagger specifications -* A validator for JSON schemas draft4 -* Helper functions to validate individual values (used by code generated by [go-swagger](https://github.com/go-swagger/go-swagger)). - * Required, RequiredNumber, RequiredString - * ReadOnly - * UniqueItems, MaxItems, MinItems - * Enum, EnumCase - * Pattern, MinLength, MaxLength - * Minimum, Maximum, MultipleOf - * FormatOf - -[Documentation](https://pkg.go.dev/github.com/go-openapi/validate) - -## FAQ - -* Does this library support OpenAPI 3? - -> No. -> This package currently only supports OpenAPI 2.0 (aka Swagger 2.0). -> There is no plan to make it evolve toward supporting OpenAPI 3.x. -> This [discussion thread](https://github.com/go-openapi/spec/issues/21) relates the full story. -> -> An early attempt to support Swagger 3 may be found at: https://github.com/go-openapi/spec3 diff --git a/vendor/github.com/go-openapi/validate/context.go b/vendor/github.com/go-openapi/validate/context.go deleted file mode 100644 index 89977173b..000000000 --- a/vendor/github.com/go-openapi/validate/context.go +++ /dev/null @@ -1,56 +0,0 @@ -package validate - -import ( - "context" -) - -// validateCtxKey is the key type of context key in this pkg -type validateCtxKey string - -const ( - operationTypeKey validateCtxKey = "operationTypeKey" -) - -type operationType string - -const ( - request operationType = "request" - response operationType = "response" - none operationType = "none" // not specified in ctx -) - -var operationTypeEnum = []operationType{request, response, none} - -// WithOperationRequest returns a new context with operationType request -// in context value -func WithOperationRequest(ctx context.Context) context.Context { - return withOperation(ctx, request) -} - -// WithOperationRequest returns a new context with operationType response -// in context value -func WithOperationResponse(ctx context.Context) context.Context { - return withOperation(ctx, response) -} - -func withOperation(ctx context.Context, operation operationType) context.Context { - return context.WithValue(ctx, operationTypeKey, operation) -} - -// extractOperationType extracts the operation type from ctx -// if not specified or of unknown value, return none operation type -func extractOperationType(ctx context.Context) operationType { - v := ctx.Value(operationTypeKey) - if v == nil { - return none - } - res, ok := v.(operationType) - if !ok { - return none - } - // validate the value is in operation enum - if err := Enum("", "", res, operationTypeEnum); err != nil { - return none - } - return res -} diff --git a/vendor/github.com/go-openapi/validate/debug.go b/vendor/github.com/go-openapi/validate/debug.go deleted file mode 100644 index 8815fd935..000000000 --- a/vendor/github.com/go-openapi/validate/debug.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "fmt" - "log" - "os" - "path/filepath" - "runtime" -) - -var ( - // Debug is true when the SWAGGER_DEBUG env var is not empty. - // It enables a more verbose logging of validators. - Debug = os.Getenv("SWAGGER_DEBUG") != "" - // validateLogger is a debug logger for this package - validateLogger *log.Logger -) - -func init() { - debugOptions() -} - -func debugOptions() { - validateLogger = log.New(os.Stdout, "validate:", log.LstdFlags) -} - -func debugLog(msg string, args ...interface{}) { - // A private, trivial trace logger, based on go-openapi/spec/expander.go:debugLog() - if Debug { - _, file1, pos1, _ := runtime.Caller(1) - validateLogger.Printf("%s:%d: %s", filepath.Base(file1), pos1, fmt.Sprintf(msg, args...)) - } -} diff --git a/vendor/github.com/go-openapi/validate/default_validator.go b/vendor/github.com/go-openapi/validate/default_validator.go deleted file mode 100644 index e0dd93839..000000000 --- a/vendor/github.com/go-openapi/validate/default_validator.go +++ /dev/null @@ -1,304 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "fmt" - "strings" - - "github.com/go-openapi/spec" -) - -// defaultValidator validates default values in a spec. -// According to Swagger spec, default values MUST validate their schema. -type defaultValidator struct { - SpecValidator *SpecValidator - visitedSchemas map[string]struct{} - schemaOptions *SchemaValidatorOptions -} - -// resetVisited resets the internal state of visited schemas -func (d *defaultValidator) resetVisited() { - if d.visitedSchemas == nil { - d.visitedSchemas = make(map[string]struct{}) - - return - } - - // TODO(go1.21): clear(ex.visitedSchemas) - for k := range d.visitedSchemas { - delete(d.visitedSchemas, k) - } -} - -func isVisited(path string, visitedSchemas map[string]struct{}) bool { - _, found := visitedSchemas[path] - if found { - return true - } - - // search for overlapping paths - var ( - parent string - suffix string - ) - for i := len(path) - 2; i >= 0; i-- { - r := path[i] - if r != '.' { - continue - } - - parent = path[0:i] - suffix = path[i+1:] - - if strings.HasSuffix(parent, suffix) { - return true - } - } - - return false -} - -// beingVisited asserts a schema is being visited -func (d *defaultValidator) beingVisited(path string) { - d.visitedSchemas[path] = struct{}{} -} - -// isVisited tells if a path has already been visited -func (d *defaultValidator) isVisited(path string) bool { - return isVisited(path, d.visitedSchemas) -} - -// Validate validates the default values declared in the swagger spec -func (d *defaultValidator) Validate() *Result { - errs := pools.poolOfResults.BorrowResult() // will redeem when merged - - if d == nil || d.SpecValidator == nil { - return errs - } - d.resetVisited() - errs.Merge(d.validateDefaultValueValidAgainstSchema()) // error - - return errs -} - -func (d *defaultValidator) validateDefaultValueValidAgainstSchema() *Result { - // every default value that is specified must validate against the schema for that property - // headers, items, parameters, schema - - res := pools.poolOfResults.BorrowResult() // will redeem when merged - s := d.SpecValidator - - for method, pathItem := range s.expandedAnalyzer().Operations() { - for path, op := range pathItem { - // parameters - for _, param := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) { - if param.Default != nil && param.Required { - res.AddWarnings(requiredHasDefaultMsg(param.Name, param.In)) - } - - // reset explored schemas to get depth-first recursive-proof exploration - d.resetVisited() - - // Check simple parameters first - // default values provided must validate against their inline definition (no explicit schema) - if param.Default != nil && param.Schema == nil { - // check param default value is valid - red := newParamValidator(¶m, s.KnownFormats, d.schemaOptions).Validate(param.Default) //#nosec - if red.HasErrorsOrWarnings() { - res.AddErrors(defaultValueDoesNotValidateMsg(param.Name, param.In)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - // Recursively follows Items and Schemas - if param.Items != nil { - red := d.validateDefaultValueItemsAgainstSchema(param.Name, param.In, ¶m, param.Items) //#nosec - if red.HasErrorsOrWarnings() { - res.AddErrors(defaultValueItemsDoesNotValidateMsg(param.Name, param.In)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - if param.Schema != nil { - // Validate default value against schema - red := d.validateDefaultValueSchemaAgainstSchema(param.Name, param.In, param.Schema) - if red.HasErrorsOrWarnings() { - res.AddErrors(defaultValueDoesNotValidateMsg(param.Name, param.In)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - } - - if op.Responses != nil { - if op.Responses.Default != nil { - // Same constraint on default Response - res.Merge(d.validateDefaultInResponse(op.Responses.Default, jsonDefault, path, 0, op.ID)) - } - // Same constraint on regular Responses - if op.Responses.StatusCodeResponses != nil { // Safeguard - for code, r := range op.Responses.StatusCodeResponses { - res.Merge(d.validateDefaultInResponse(&r, "response", path, code, op.ID)) //#nosec - } - } - } else if op.ID != "" { - // Empty op.ID means there is no meaningful operation: no need to report a specific message - res.AddErrors(noValidResponseMsg(op.ID)) - } - } - } - if s.spec.Spec().Definitions != nil { // Safeguard - // reset explored schemas to get depth-first recursive-proof exploration - d.resetVisited() - for nm, sch := range s.spec.Spec().Definitions { - res.Merge(d.validateDefaultValueSchemaAgainstSchema("definitions."+nm, "body", &sch)) //#nosec - } - } - return res -} - -func (d *defaultValidator) validateDefaultInResponse(resp *spec.Response, responseType, path string, responseCode int, operationID string) *Result { - s := d.SpecValidator - - response, res := responseHelp.expandResponseRef(resp, path, s) - if !res.IsValid() { - return res - } - - responseName, responseCodeAsStr := responseHelp.responseMsgVariants(responseType, responseCode) - - if response.Headers != nil { // Safeguard - for nm, h := range response.Headers { - // reset explored schemas to get depth-first recursive-proof exploration - d.resetVisited() - - if h.Default != nil { - red := newHeaderValidator(nm, &h, s.KnownFormats, d.schemaOptions).Validate(h.Default) //#nosec - if red.HasErrorsOrWarnings() { - res.AddErrors(defaultValueHeaderDoesNotValidateMsg(operationID, nm, responseName)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - // Headers have inline definition, like params - if h.Items != nil { - red := d.validateDefaultValueItemsAgainstSchema(nm, "header", &h, h.Items) //#nosec - if red.HasErrorsOrWarnings() { - res.AddErrors(defaultValueHeaderItemsDoesNotValidateMsg(operationID, nm, responseName)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - if _, err := compileRegexp(h.Pattern); err != nil { - res.AddErrors(invalidPatternInHeaderMsg(operationID, nm, responseName, h.Pattern, err)) - } - - // Headers don't have schema - } - } - if response.Schema != nil { - // reset explored schemas to get depth-first recursive-proof exploration - d.resetVisited() - - red := d.validateDefaultValueSchemaAgainstSchema(responseCodeAsStr, "response", response.Schema) - if red.HasErrorsOrWarnings() { - // Additional message to make sure the context of the error is not lost - res.AddErrors(defaultValueInDoesNotValidateMsg(operationID, responseName)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - return res -} - -func (d *defaultValidator) validateDefaultValueSchemaAgainstSchema(path, in string, schema *spec.Schema) *Result { - if schema == nil || d.isVisited(path) { - // Avoids recursing if we are already done with that check - return nil - } - d.beingVisited(path) - res := pools.poolOfResults.BorrowResult() - s := d.SpecValidator - - if schema.Default != nil { - res.Merge( - newSchemaValidator(schema, s.spec.Spec(), path+".default", s.KnownFormats, d.schemaOptions).Validate(schema.Default), - ) - } - if schema.Items != nil { - if schema.Items.Schema != nil { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+".items.default", in, schema.Items.Schema)) - } - // Multiple schemas in items - if schema.Items.Schemas != nil { // Safeguard - for i, sch := range schema.Items.Schemas { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.items[%d].default", path, i), in, &sch)) //#nosec - } - } - } - if _, err := compileRegexp(schema.Pattern); err != nil { - res.AddErrors(invalidPatternInMsg(path, in, schema.Pattern)) - } - if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil { - // NOTE: we keep validating values, even though additionalItems is not supported by Swagger 2.0 (and 3.0 as well) - res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+".additionalItems", in, schema.AdditionalItems.Schema)) - } - for propName, prop := range schema.Properties { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec - } - for propName, prop := range schema.PatternProperties { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec - } - if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(path+".additionalProperties", in, schema.AdditionalProperties.Schema)) - } - if schema.AllOf != nil { - for i, aoSch := range schema.AllOf { - res.Merge(d.validateDefaultValueSchemaAgainstSchema(fmt.Sprintf("%s.allOf[%d]", path, i), in, &aoSch)) //#nosec - } - } - return res -} - -// TODO: Temporary duplicated code. Need to refactor with examples - -func (d *defaultValidator) validateDefaultValueItemsAgainstSchema(path, in string, root interface{}, items *spec.Items) *Result { - res := pools.poolOfResults.BorrowResult() - s := d.SpecValidator - if items != nil { - if items.Default != nil { - res.Merge( - newItemsValidator(path, in, items, root, s.KnownFormats, d.schemaOptions).Validate(0, items.Default), - ) - } - if items.Items != nil { - res.Merge(d.validateDefaultValueItemsAgainstSchema(path+"[0].default", in, root, items.Items)) - } - if _, err := compileRegexp(items.Pattern); err != nil { - res.AddErrors(invalidPatternInMsg(path, in, items.Pattern)) - } - } - return res -} diff --git a/vendor/github.com/go-openapi/validate/doc.go b/vendor/github.com/go-openapi/validate/doc.go deleted file mode 100644 index d2b901eab..000000000 --- a/vendor/github.com/go-openapi/validate/doc.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* -Package validate provides methods to validate a swagger specification, -as well as tools to validate data against their schema. - -This package follows Swagger 2.0. specification (aka OpenAPI 2.0). Reference -can be found here: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md. - -# Validating a specification - -Validates a spec document (from JSON or YAML) against the JSON schema for swagger, -then checks a number of extra rules that can't be expressed in JSON schema. - -Entry points: - - Spec() - - NewSpecValidator() - - SpecValidator.Validate() - -Reported as errors: - - [x] definition can't declare a property that's already defined by one of its ancestors - [x] definition's ancestor can't be a descendant of the same model - [x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method. Validation can be laxed by disabling StrictPathParamUniqueness. - [x] each security reference should contain only unique scopes - [x] each security scope in a security definition should be unique - [x] parameters in path must be unique - [x] each path parameter must correspond to a parameter placeholder and vice versa - [x] each referenceable definition must have references - [x] each definition property listed in the required array must be defined in the properties of the model - [x] each parameter should have a unique `name` and `type` combination - [x] each operation should have only 1 parameter of type body - [x] each reference must point to a valid object - [x] every default value that is specified must validate against the schema for that property - [x] items property is required for all schemas/definitions of type `array` - [x] path parameters must be declared a required - [x] headers must not contain $ref - [x] schema and property examples provided must validate against their respective object's schema - [x] examples provided must validate their schema - -Reported as warnings: - - [x] path parameters should not contain any of [{,},\w] - [x] empty path - [x] unused definitions - [x] unsupported validation of examples on non-JSON media types - [x] examples in response without schema - [x] readOnly properties should not be required - -# Validating a schema - -The schema validation toolkit validates data against JSON-schema-draft 04 schema. - -It is tested against the full json-schema-testing-suite (https://github.com/json-schema-org/JSON-Schema-Test-Suite), -except for the optional part (bignum, ECMA regexp, ...). - -It supports the complete JSON-schema vocabulary, including keywords not supported by Swagger (e.g. additionalItems, ...) - -Entry points: - - AgainstSchema() - - ... - -# Known limitations - -With the current version of this package, the following aspects of swagger are not yet supported: - - [ ] errors and warnings are not reported with key/line number in spec - [ ] default values and examples on responses only support application/json producer type - [ ] invalid numeric constraints (such as Minimum, etc..) are not checked except for default and example values - [ ] rules for collectionFormat are not implemented - [ ] no validation rule for polymorphism support (discriminator) [not done here] - [ ] valid js ECMA regexp not supported by Go regexp engine are considered invalid - [ ] arbitrary large numbers are not supported: max is math.MaxFloat64 -*/ -package validate diff --git a/vendor/github.com/go-openapi/validate/example_validator.go b/vendor/github.com/go-openapi/validate/example_validator.go deleted file mode 100644 index d08956973..000000000 --- a/vendor/github.com/go-openapi/validate/example_validator.go +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "fmt" - - "github.com/go-openapi/spec" -) - -// ExampleValidator validates example values defined in a spec -type exampleValidator struct { - SpecValidator *SpecValidator - visitedSchemas map[string]struct{} - schemaOptions *SchemaValidatorOptions -} - -// resetVisited resets the internal state of visited schemas -func (ex *exampleValidator) resetVisited() { - if ex.visitedSchemas == nil { - ex.visitedSchemas = make(map[string]struct{}) - - return - } - - // TODO(go1.21): clear(ex.visitedSchemas) - for k := range ex.visitedSchemas { - delete(ex.visitedSchemas, k) - } -} - -// beingVisited asserts a schema is being visited -func (ex *exampleValidator) beingVisited(path string) { - ex.visitedSchemas[path] = struct{}{} -} - -// isVisited tells if a path has already been visited -func (ex *exampleValidator) isVisited(path string) bool { - return isVisited(path, ex.visitedSchemas) -} - -// Validate validates the example values declared in the swagger spec -// Example values MUST conform to their schema. -// -// With Swagger 2.0, examples are supported in: -// - schemas -// - individual property -// - responses -func (ex *exampleValidator) Validate() *Result { - errs := pools.poolOfResults.BorrowResult() - - if ex == nil || ex.SpecValidator == nil { - return errs - } - ex.resetVisited() - errs.Merge(ex.validateExampleValueValidAgainstSchema()) // error - - - return errs -} - -func (ex *exampleValidator) validateExampleValueValidAgainstSchema() *Result { - // every example value that is specified must validate against the schema for that property - // in: schemas, properties, object, items - // not in: headers, parameters without schema - - res := pools.poolOfResults.BorrowResult() - s := ex.SpecValidator - - for method, pathItem := range s.expandedAnalyzer().Operations() { - for path, op := range pathItem { - // parameters - for _, param := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) { - - // As of swagger 2.0, Examples are not supported in simple parameters - // However, it looks like it is supported by go-openapi - - // reset explored schemas to get depth-first recursive-proof exploration - ex.resetVisited() - - // Check simple parameters first - // default values provided must validate against their inline definition (no explicit schema) - if param.Example != nil && param.Schema == nil { - // check param default value is valid - red := newParamValidator(¶m, s.KnownFormats, ex.schemaOptions).Validate(param.Example) //#nosec - if red.HasErrorsOrWarnings() { - res.AddWarnings(exampleValueDoesNotValidateMsg(param.Name, param.In)) - res.MergeAsWarnings(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - // Recursively follows Items and Schemas - if param.Items != nil { - red := ex.validateExampleValueItemsAgainstSchema(param.Name, param.In, ¶m, param.Items) //#nosec - if red.HasErrorsOrWarnings() { - res.AddWarnings(exampleValueItemsDoesNotValidateMsg(param.Name, param.In)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - if param.Schema != nil { - // Validate example value against schema - red := ex.validateExampleValueSchemaAgainstSchema(param.Name, param.In, param.Schema) - if red.HasErrorsOrWarnings() { - res.AddWarnings(exampleValueDoesNotValidateMsg(param.Name, param.In)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - } - - if op.Responses != nil { - if op.Responses.Default != nil { - // Same constraint on default Response - res.Merge(ex.validateExampleInResponse(op.Responses.Default, jsonDefault, path, 0, op.ID)) - } - // Same constraint on regular Responses - if op.Responses.StatusCodeResponses != nil { // Safeguard - for code, r := range op.Responses.StatusCodeResponses { - res.Merge(ex.validateExampleInResponse(&r, "response", path, code, op.ID)) //#nosec - } - } - } else if op.ID != "" { - // Empty op.ID means there is no meaningful operation: no need to report a specific message - res.AddErrors(noValidResponseMsg(op.ID)) - } - } - } - if s.spec.Spec().Definitions != nil { // Safeguard - // reset explored schemas to get depth-first recursive-proof exploration - ex.resetVisited() - for nm, sch := range s.spec.Spec().Definitions { - res.Merge(ex.validateExampleValueSchemaAgainstSchema("definitions."+nm, "body", &sch)) //#nosec - } - } - return res -} - -func (ex *exampleValidator) validateExampleInResponse(resp *spec.Response, responseType, path string, responseCode int, operationID string) *Result { - s := ex.SpecValidator - - response, res := responseHelp.expandResponseRef(resp, path, s) - if !res.IsValid() { // Safeguard - return res - } - - responseName, responseCodeAsStr := responseHelp.responseMsgVariants(responseType, responseCode) - - if response.Headers != nil { // Safeguard - for nm, h := range response.Headers { - // reset explored schemas to get depth-first recursive-proof exploration - ex.resetVisited() - - if h.Example != nil { - red := newHeaderValidator(nm, &h, s.KnownFormats, ex.schemaOptions).Validate(h.Example) //#nosec - if red.HasErrorsOrWarnings() { - res.AddWarnings(exampleValueHeaderDoesNotValidateMsg(operationID, nm, responseName)) - res.MergeAsWarnings(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - // Headers have inline definition, like params - if h.Items != nil { - red := ex.validateExampleValueItemsAgainstSchema(nm, "header", &h, h.Items) //#nosec - if red.HasErrorsOrWarnings() { - res.AddWarnings(exampleValueHeaderItemsDoesNotValidateMsg(operationID, nm, responseName)) - res.MergeAsWarnings(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - if _, err := compileRegexp(h.Pattern); err != nil { - res.AddErrors(invalidPatternInHeaderMsg(operationID, nm, responseName, h.Pattern, err)) - } - - // Headers don't have schema - } - } - if response.Schema != nil { - // reset explored schemas to get depth-first recursive-proof exploration - ex.resetVisited() - - red := ex.validateExampleValueSchemaAgainstSchema(responseCodeAsStr, "response", response.Schema) - if red.HasErrorsOrWarnings() { - // Additional message to make sure the context of the error is not lost - res.AddWarnings(exampleValueInDoesNotValidateMsg(operationID, responseName)) - res.Merge(red) - } else if red.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(red) - } - } - - if response.Examples != nil { - if response.Schema != nil { - if example, ok := response.Examples["application/json"]; ok { - res.MergeAsWarnings( - newSchemaValidator(response.Schema, s.spec.Spec(), path+".examples", s.KnownFormats, s.schemaOptions).Validate(example), - ) - } else { - // TODO: validate other media types too - res.AddWarnings(examplesMimeNotSupportedMsg(operationID, responseName)) - } - } else { - res.AddWarnings(examplesWithoutSchemaMsg(operationID, responseName)) - } - } - return res -} - -func (ex *exampleValidator) validateExampleValueSchemaAgainstSchema(path, in string, schema *spec.Schema) *Result { - if schema == nil || ex.isVisited(path) { - // Avoids recursing if we are already done with that check - return nil - } - ex.beingVisited(path) - s := ex.SpecValidator - res := pools.poolOfResults.BorrowResult() - - if schema.Example != nil { - res.MergeAsWarnings( - newSchemaValidator(schema, s.spec.Spec(), path+".example", s.KnownFormats, ex.schemaOptions).Validate(schema.Example), - ) - } - if schema.Items != nil { - if schema.Items.Schema != nil { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+".items.example", in, schema.Items.Schema)) - } - // Multiple schemas in items - if schema.Items.Schemas != nil { // Safeguard - for i, sch := range schema.Items.Schemas { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.items[%d].example", path, i), in, &sch)) //#nosec - } - } - } - if _, err := compileRegexp(schema.Pattern); err != nil { - res.AddErrors(invalidPatternInMsg(path, in, schema.Pattern)) - } - if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil { - // NOTE: we keep validating values, even though additionalItems is unsupported in Swagger 2.0 (and 3.0 as well) - res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+".additionalItems", in, schema.AdditionalItems.Schema)) - } - for propName, prop := range schema.Properties { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec - } - for propName, prop := range schema.PatternProperties { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+"."+propName, in, &prop)) //#nosec - } - if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(path+".additionalProperties", in, schema.AdditionalProperties.Schema)) - } - if schema.AllOf != nil { - for i, aoSch := range schema.AllOf { - res.Merge(ex.validateExampleValueSchemaAgainstSchema(fmt.Sprintf("%s.allOf[%d]", path, i), in, &aoSch)) //#nosec - } - } - return res -} - -// TODO: Temporary duplicated code. Need to refactor with examples -// - -func (ex *exampleValidator) validateExampleValueItemsAgainstSchema(path, in string, root interface{}, items *spec.Items) *Result { - res := pools.poolOfResults.BorrowResult() - s := ex.SpecValidator - if items != nil { - if items.Example != nil { - res.MergeAsWarnings( - newItemsValidator(path, in, items, root, s.KnownFormats, ex.schemaOptions).Validate(0, items.Example), - ) - } - if items.Items != nil { - res.Merge(ex.validateExampleValueItemsAgainstSchema(path+"[0].example", in, root, items.Items)) - } - if _, err := compileRegexp(items.Pattern); err != nil { - res.AddErrors(invalidPatternInMsg(path, in, items.Pattern)) - } - } - - return res -} diff --git a/vendor/github.com/go-openapi/validate/formats.go b/vendor/github.com/go-openapi/validate/formats.go deleted file mode 100644 index f4e355213..000000000 --- a/vendor/github.com/go-openapi/validate/formats.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "reflect" - - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" -) - -type formatValidator struct { - Path string - In string - Format string - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions -} - -func newFormatValidator(path, in, format string, formats strfmt.Registry, opts *SchemaValidatorOptions) *formatValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var f *formatValidator - if opts.recycleValidators { - f = pools.poolOfFormatValidators.BorrowValidator() - } else { - f = new(formatValidator) - } - - f.Path = path - f.In = in - f.Format = format - f.KnownFormats = formats - f.Options = opts - - return f -} - -func (f *formatValidator) SetPath(path string) { - f.Path = path -} - -func (f *formatValidator) Applies(source interface{}, kind reflect.Kind) bool { - if source == nil || f.KnownFormats == nil { - return false - } - - switch source := source.(type) { - case *spec.Items: - return kind == reflect.String && f.KnownFormats.ContainsName(source.Format) - case *spec.Parameter: - return kind == reflect.String && f.KnownFormats.ContainsName(source.Format) - case *spec.Schema: - return kind == reflect.String && f.KnownFormats.ContainsName(source.Format) - case *spec.Header: - return kind == reflect.String && f.KnownFormats.ContainsName(source.Format) - default: - return false - } -} - -func (f *formatValidator) Validate(val interface{}) *Result { - if f.Options.recycleValidators { - defer func() { - f.redeem() - }() - } - - var result *Result - if f.Options.recycleResult { - result = pools.poolOfResults.BorrowResult() - } else { - result = new(Result) - } - - if err := FormatOf(f.Path, f.In, f.Format, val.(string), f.KnownFormats); err != nil { - result.AddErrors(err) - } - - return result -} - -func (f *formatValidator) redeem() { - pools.poolOfFormatValidators.RedeemValidator(f) -} diff --git a/vendor/github.com/go-openapi/validate/helpers.go b/vendor/github.com/go-openapi/validate/helpers.go deleted file mode 100644 index 757e403d9..000000000 --- a/vendor/github.com/go-openapi/validate/helpers.go +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -// TODO: define this as package validate/internal -// This must be done while keeping CI intact with all tests and test coverage - -import ( - "reflect" - "strconv" - "strings" - - "github.com/go-openapi/errors" - "github.com/go-openapi/spec" -) - -const ( - swaggerBody = "body" - swaggerExample = "example" - swaggerExamples = "examples" -) - -const ( - objectType = "object" - arrayType = "array" - stringType = "string" - integerType = "integer" - numberType = "number" - booleanType = "boolean" - fileType = "file" - nullType = "null" -) - -const ( - jsonProperties = "properties" - jsonItems = "items" - jsonType = "type" - // jsonSchema = "schema" - jsonDefault = "default" -) - -const ( - stringFormatDate = "date" - stringFormatDateTime = "date-time" - stringFormatPassword = "password" - stringFormatByte = "byte" - // stringFormatBinary = "binary" - stringFormatCreditCard = "creditcard" - stringFormatDuration = "duration" - stringFormatEmail = "email" - stringFormatHexColor = "hexcolor" - stringFormatHostname = "hostname" - stringFormatIPv4 = "ipv4" - stringFormatIPv6 = "ipv6" - stringFormatISBN = "isbn" - stringFormatISBN10 = "isbn10" - stringFormatISBN13 = "isbn13" - stringFormatMAC = "mac" - stringFormatBSONObjectID = "bsonobjectid" - stringFormatRGBColor = "rgbcolor" - stringFormatSSN = "ssn" - stringFormatURI = "uri" - stringFormatUUID = "uuid" - stringFormatUUID3 = "uuid3" - stringFormatUUID4 = "uuid4" - stringFormatUUID5 = "uuid5" - - integerFormatInt32 = "int32" - integerFormatInt64 = "int64" - integerFormatUInt32 = "uint32" - integerFormatUInt64 = "uint64" - - numberFormatFloat32 = "float32" - numberFormatFloat64 = "float64" - numberFormatFloat = "float" - numberFormatDouble = "double" -) - -// Helpers available at the package level -var ( - pathHelp *pathHelper - valueHelp *valueHelper - errorHelp *errorHelper - paramHelp *paramHelper - responseHelp *responseHelper -) - -type errorHelper struct { - // A collection of unexported helpers for error construction -} - -func (h *errorHelper) sErr(err errors.Error, recycle bool) *Result { - // Builds a Result from standard errors.Error - var result *Result - if recycle { - result = pools.poolOfResults.BorrowResult() - } else { - result = new(Result) - } - result.Errors = []error{err} - - return result -} - -func (h *errorHelper) addPointerError(res *Result, err error, ref string, fromPath string) *Result { - // Provides more context on error messages - // reported by the jsoinpointer package by altering the passed Result - if err != nil { - res.AddErrors(cannotResolveRefMsg(fromPath, ref, err)) - } - return res -} - -type pathHelper struct { - // A collection of unexported helpers for path validation -} - -func (h *pathHelper) stripParametersInPath(path string) string { - // Returns a path stripped from all path parameters, with multiple or trailing slashes removed. - // - // Stripping is performed on a slash-separated basis, e.g '/a{/b}' remains a{/b} and not /a. - // - Trailing "/" make a difference, e.g. /a/ !~ /a (ex: canary/bitbucket.org/swagger.json) - // - presence or absence of a parameter makes a difference, e.g. /a/{log} !~ /a/ (ex: canary/kubernetes/swagger.json) - - // Regexp to extract parameters from path, with surrounding {}. - // NOTE: important non-greedy modifier - rexParsePathParam := mustCompileRegexp(`{[^{}]+?}`) - strippedSegments := []string{} - - for _, segment := range strings.Split(path, "/") { - strippedSegments = append(strippedSegments, rexParsePathParam.ReplaceAllString(segment, "X")) - } - return strings.Join(strippedSegments, "/") -} - -func (h *pathHelper) extractPathParams(path string) (params []string) { - // Extracts all params from a path, with surrounding "{}" - rexParsePathParam := mustCompileRegexp(`{[^{}]+?}`) - - for _, segment := range strings.Split(path, "/") { - for _, v := range rexParsePathParam.FindAllStringSubmatch(segment, -1) { - params = append(params, v...) - } - } - return -} - -type valueHelper struct { - // A collection of unexported helpers for value validation -} - -func (h *valueHelper) asInt64(val interface{}) int64 { - // Number conversion function for int64, without error checking - // (implements an implicit type upgrade). - v := reflect.ValueOf(val) - switch v.Kind() { //nolint:exhaustive - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return int64(v.Uint()) - case reflect.Float32, reflect.Float64: - return int64(v.Float()) - default: - // panic("Non numeric value in asInt64()") - return 0 - } -} - -func (h *valueHelper) asUint64(val interface{}) uint64 { - // Number conversion function for uint64, without error checking - // (implements an implicit type upgrade). - v := reflect.ValueOf(val) - switch v.Kind() { //nolint:exhaustive - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return uint64(v.Int()) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return v.Uint() - case reflect.Float32, reflect.Float64: - return uint64(v.Float()) - default: - // panic("Non numeric value in asUint64()") - return 0 - } -} - -// Same for unsigned floats -func (h *valueHelper) asFloat64(val interface{}) float64 { - // Number conversion function for float64, without error checking - // (implements an implicit type upgrade). - v := reflect.ValueOf(val) - switch v.Kind() { //nolint:exhaustive - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return float64(v.Int()) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return float64(v.Uint()) - case reflect.Float32, reflect.Float64: - return v.Float() - default: - // panic("Non numeric value in asFloat64()") - return 0 - } -} - -type paramHelper struct { - // A collection of unexported helpers for parameters resolution -} - -func (h *paramHelper) safeExpandedParamsFor(path, method, operationID string, res *Result, s *SpecValidator) (params []spec.Parameter) { - operation, ok := s.expandedAnalyzer().OperationFor(method, path) - if ok { - // expand parameters first if necessary - resolvedParams := []spec.Parameter{} - for _, ppr := range operation.Parameters { - resolvedParam, red := h.resolveParam(path, method, operationID, &ppr, s) //#nosec - res.Merge(red) - if resolvedParam != nil { - resolvedParams = append(resolvedParams, *resolvedParam) - } - } - // remove params with invalid expansion from Slice - operation.Parameters = resolvedParams - - for _, ppr := range s.expandedAnalyzer().SafeParamsFor(method, path, - func(_ spec.Parameter, err error) bool { - // since params have already been expanded, there are few causes for error - res.AddErrors(someParametersBrokenMsg(path, method, operationID)) - // original error from analyzer - res.AddErrors(err) - return true - }) { - params = append(params, ppr) - } - } - return -} - -func (h *paramHelper) resolveParam(path, method, operationID string, param *spec.Parameter, s *SpecValidator) (*spec.Parameter, *Result) { - // Ensure parameter is expanded - var err error - res := new(Result) - isRef := param.Ref.String() != "" - if s.spec.SpecFilePath() == "" { - err = spec.ExpandParameterWithRoot(param, s.spec.Spec(), nil) - } else { - err = spec.ExpandParameter(param, s.spec.SpecFilePath()) - - } - if err != nil { // Safeguard - // NOTE: we may enter here when the whole parameter is an unresolved $ref - refPath := strings.Join([]string{"\"" + path + "\"", method}, ".") - errorHelp.addPointerError(res, err, param.Ref.String(), refPath) - return nil, res - } - res.Merge(h.checkExpandedParam(param, param.Name, param.In, operationID, isRef)) - return param, res -} - -func (h *paramHelper) checkExpandedParam(pr *spec.Parameter, path, in, operation string, isRef bool) *Result { - // Secure parameter structure after $ref resolution - res := new(Result) - simpleZero := spec.SimpleSchema{} - // Try to explain why... best guess - switch { - case pr.In == swaggerBody && (pr.SimpleSchema != simpleZero && pr.SimpleSchema.Type != objectType): - if isRef { - // Most likely, a $ref with a sibling is an unwanted situation: in itself this is a warning... - // but we detect it because of the following error: - // schema took over Parameter for an unexplained reason - res.AddWarnings(refShouldNotHaveSiblingsMsg(path, operation)) - } - res.AddErrors(invalidParameterDefinitionMsg(path, in, operation)) - case pr.In != swaggerBody && pr.Schema != nil: - if isRef { - res.AddWarnings(refShouldNotHaveSiblingsMsg(path, operation)) - } - res.AddErrors(invalidParameterDefinitionAsSchemaMsg(path, in, operation)) - case (pr.In == swaggerBody && pr.Schema == nil) || (pr.In != swaggerBody && pr.SimpleSchema == simpleZero): - // Other unexpected mishaps - res.AddErrors(invalidParameterDefinitionMsg(path, in, operation)) - } - return res -} - -type responseHelper struct { - // A collection of unexported helpers for response resolution -} - -func (r *responseHelper) expandResponseRef( - response *spec.Response, - path string, s *SpecValidator) (*spec.Response, *Result) { - // Ensure response is expanded - var err error - res := new(Result) - if s.spec.SpecFilePath() == "" { - // there is no physical document to resolve $ref in response - err = spec.ExpandResponseWithRoot(response, s.spec.Spec(), nil) - } else { - err = spec.ExpandResponse(response, s.spec.SpecFilePath()) - } - if err != nil { // Safeguard - // NOTE: we may enter here when the whole response is an unresolved $ref. - errorHelp.addPointerError(res, err, response.Ref.String(), path) - return nil, res - } - - return response, res -} - -func (r *responseHelper) responseMsgVariants( - responseType string, - responseCode int) (responseName, responseCodeAsStr string) { - // Path variants for messages - if responseType == jsonDefault { - responseCodeAsStr = jsonDefault - responseName = "default response" - } else { - responseCodeAsStr = strconv.Itoa(responseCode) - responseName = "response " + responseCodeAsStr - } - return -} diff --git a/vendor/github.com/go-openapi/validate/object_validator.go b/vendor/github.com/go-openapi/validate/object_validator.go deleted file mode 100644 index dff73fa98..000000000 --- a/vendor/github.com/go-openapi/validate/object_validator.go +++ /dev/null @@ -1,431 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "fmt" - "reflect" - "strings" - - "github.com/go-openapi/errors" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" -) - -type objectValidator struct { - Path string - In string - MaxProperties *int64 - MinProperties *int64 - Required []string - Properties map[string]spec.Schema - AdditionalProperties *spec.SchemaOrBool - PatternProperties map[string]spec.Schema - Root interface{} - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions - splitPath []string -} - -func newObjectValidator(path, in string, - maxProperties, minProperties *int64, required []string, properties spec.SchemaProperties, - additionalProperties *spec.SchemaOrBool, patternProperties spec.SchemaProperties, - root interface{}, formats strfmt.Registry, opts *SchemaValidatorOptions) *objectValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var v *objectValidator - if opts.recycleValidators { - v = pools.poolOfObjectValidators.BorrowValidator() - } else { - v = new(objectValidator) - } - - v.Path = path - v.In = in - v.MaxProperties = maxProperties - v.MinProperties = minProperties - v.Required = required - v.Properties = properties - v.AdditionalProperties = additionalProperties - v.PatternProperties = patternProperties - v.Root = root - v.KnownFormats = formats - v.Options = opts - v.splitPath = strings.Split(v.Path, ".") - - return v -} - -func (o *objectValidator) SetPath(path string) { - o.Path = path - o.splitPath = strings.Split(path, ".") -} - -func (o *objectValidator) Applies(source interface{}, kind reflect.Kind) bool { - // TODO: this should also work for structs - // there is a problem in the type validator where it will be unhappy about null values - // so that requires more testing - _, isSchema := source.(*spec.Schema) - return isSchema && (kind == reflect.Map || kind == reflect.Struct) -} - -func (o *objectValidator) isProperties() bool { - p := o.splitPath - return len(p) > 1 && p[len(p)-1] == jsonProperties && p[len(p)-2] != jsonProperties -} - -func (o *objectValidator) isDefault() bool { - p := o.splitPath - return len(p) > 1 && p[len(p)-1] == jsonDefault && p[len(p)-2] != jsonDefault -} - -func (o *objectValidator) isExample() bool { - p := o.splitPath - return len(p) > 1 && (p[len(p)-1] == swaggerExample || p[len(p)-1] == swaggerExamples) && p[len(p)-2] != swaggerExample -} - -func (o *objectValidator) checkArrayMustHaveItems(res *Result, val map[string]interface{}) { - // for swagger 2.0 schemas, there is an additional constraint to have array items defined explicitly. - // with pure jsonschema draft 4, one may have arrays with undefined items (i.e. any type). - if val == nil { - return - } - - t, typeFound := val[jsonType] - if !typeFound { - return - } - - tpe, isString := t.(string) - if !isString || tpe != arrayType { - return - } - - item, itemsKeyFound := val[jsonItems] - if itemsKeyFound { - return - } - - res.AddErrors(errors.Required(jsonItems, o.Path, item)) -} - -func (o *objectValidator) checkItemsMustBeTypeArray(res *Result, val map[string]interface{}) { - if val == nil { - return - } - - if o.isProperties() || o.isDefault() || o.isExample() { - return - } - - _, itemsKeyFound := val[jsonItems] - if !itemsKeyFound { - return - } - - t, typeFound := val[jsonType] - if !typeFound { - // there is no type - res.AddErrors(errors.Required(jsonType, o.Path, t)) - } - - if tpe, isString := t.(string); !isString || tpe != arrayType { - res.AddErrors(errors.InvalidType(o.Path, o.In, arrayType, nil)) - } -} - -func (o *objectValidator) precheck(res *Result, val map[string]interface{}) { - if o.Options.EnableArrayMustHaveItemsCheck { - o.checkArrayMustHaveItems(res, val) - } - if o.Options.EnableObjectArrayTypeCheck { - o.checkItemsMustBeTypeArray(res, val) - } -} - -func (o *objectValidator) Validate(data interface{}) *Result { - if o.Options.recycleValidators { - defer func() { - o.redeem() - }() - } - - var val map[string]interface{} - if data != nil { - var ok bool - val, ok = data.(map[string]interface{}) - if !ok { - return errorHelp.sErr(invalidObjectMsg(o.Path, o.In), o.Options.recycleResult) - } - } - numKeys := int64(len(val)) - - if o.MinProperties != nil && numKeys < *o.MinProperties { - return errorHelp.sErr(errors.TooFewProperties(o.Path, o.In, *o.MinProperties), o.Options.recycleResult) - } - if o.MaxProperties != nil && numKeys > *o.MaxProperties { - return errorHelp.sErr(errors.TooManyProperties(o.Path, o.In, *o.MaxProperties), o.Options.recycleResult) - } - - var res *Result - if o.Options.recycleResult { - res = pools.poolOfResults.BorrowResult() - } else { - res = new(Result) - } - - o.precheck(res, val) - - // check validity of field names - if o.AdditionalProperties != nil && !o.AdditionalProperties.Allows { - // Case: additionalProperties: false - o.validateNoAdditionalProperties(val, res) - } else { - // Cases: empty additionalProperties (implying: true), or additionalProperties: true, or additionalProperties: { <<schema>> } - o.validateAdditionalProperties(val, res) - } - - o.validatePropertiesSchema(val, res) - - // Check patternProperties - // TODO: it looks like we have done that twice in many cases - for key, value := range val { - _, regularProperty := o.Properties[key] - matched, _, patterns := o.validatePatternProperty(key, value, res) // applies to regular properties as well - if regularProperty || !matched { - continue - } - - for _, pName := range patterns { - if v, ok := o.PatternProperties[pName]; ok { - r := newSchemaValidator(&v, o.Root, o.Path+"."+key, o.KnownFormats, o.Options).Validate(value) - res.mergeForField(data.(map[string]interface{}), key, r) - } - } - } - - return res -} - -func (o *objectValidator) validateNoAdditionalProperties(val map[string]interface{}, res *Result) { - for k := range val { - if k == "$schema" || k == "id" { - // special properties "$schema" and "id" are ignored - continue - } - - _, regularProperty := o.Properties[k] - if regularProperty { - continue - } - - matched := false - for pk := range o.PatternProperties { - re, err := compileRegexp(pk) - if err != nil { - continue - } - if matches := re.MatchString(k); matches { - matched = true - break - } - } - if matched { - continue - } - - res.AddErrors(errors.PropertyNotAllowed(o.Path, o.In, k)) - - // BUG(fredbi): This section should move to a part dedicated to spec validation as - // it will conflict with regular schemas where a property "headers" is defined. - - // - // Croaks a more explicit message on top of the standard one - // on some recognized cases. - // - // NOTE: edge cases with invalid type assertion are simply ignored here. - // NOTE: prefix your messages here by "IMPORTANT!" so there are not filtered - // by higher level callers (the IMPORTANT! tag will be eventually - // removed). - if k != "headers" || val[k] == nil { - continue - } - - // $ref is forbidden in header - headers, mapOk := val[k].(map[string]interface{}) - if !mapOk { - continue - } - - for headerKey, headerBody := range headers { - if headerBody == nil { - continue - } - - headerSchema, mapOfMapOk := headerBody.(map[string]interface{}) - if !mapOfMapOk { - continue - } - - _, found := headerSchema["$ref"] - if !found { - continue - } - - refString, stringOk := headerSchema["$ref"].(string) - if !stringOk { - continue - } - - msg := strings.Join([]string{", one may not use $ref=\":", refString, "\""}, "") - res.AddErrors(refNotAllowedInHeaderMsg(o.Path, headerKey, msg)) - /* - case "$ref": - if val[k] != nil { - // TODO: check context of that ref: warn about siblings, check against invalid context - } - */ - } - } -} - -func (o *objectValidator) validateAdditionalProperties(val map[string]interface{}, res *Result) { - for key, value := range val { - _, regularProperty := o.Properties[key] - if regularProperty { - continue - } - - // Validates property against "patternProperties" if applicable - // BUG(fredbi): succeededOnce is always false - - // NOTE: how about regular properties which do not match patternProperties? - matched, succeededOnce, _ := o.validatePatternProperty(key, value, res) - if matched || succeededOnce { - continue - } - - if o.AdditionalProperties == nil || o.AdditionalProperties.Schema == nil { - continue - } - - // Cases: properties which are not regular properties and have not been matched by the PatternProperties validator - // AdditionalProperties as Schema - r := newSchemaValidator(o.AdditionalProperties.Schema, o.Root, o.Path+"."+key, o.KnownFormats, o.Options).Validate(value) - res.mergeForField(val, key, r) - } - // Valid cases: additionalProperties: true or undefined -} - -func (o *objectValidator) validatePropertiesSchema(val map[string]interface{}, res *Result) { - createdFromDefaults := map[string]struct{}{} - - // Property types: - // - regular Property - pSchema := pools.poolOfSchemas.BorrowSchema() // recycle a spec.Schema object which lifespan extends only to the validation of properties - defer func() { - pools.poolOfSchemas.RedeemSchema(pSchema) - }() - - for pName := range o.Properties { - *pSchema = o.Properties[pName] - var rName string - if o.Path == "" { - rName = pName - } else { - rName = o.Path + "." + pName - } - - // Recursively validates each property against its schema - v, ok := val[pName] - if ok { - r := newSchemaValidator(pSchema, o.Root, rName, o.KnownFormats, o.Options).Validate(v) - res.mergeForField(val, pName, r) - - continue - } - - if pSchema.Default != nil { - // if a default value is defined, creates the property from defaults - // NOTE: JSON schema does not enforce default values to be valid against schema. Swagger does. - createdFromDefaults[pName] = struct{}{} - if !o.Options.skipSchemataResult { - res.addPropertySchemata(val, pName, pSchema) // this shallow-clones the content of the pSchema pointer - } - } - } - - if len(o.Required) == 0 { - return - } - - // Check required properties - for _, k := range o.Required { - v, ok := val[k] - if ok { - continue - } - _, isCreatedFromDefaults := createdFromDefaults[k] - if isCreatedFromDefaults { - continue - } - - res.AddErrors(errors.Required(fmt.Sprintf("%s.%s", o.Path, k), o.In, v)) - } -} - -// TODO: succeededOnce is not used anywhere -func (o *objectValidator) validatePatternProperty(key string, value interface{}, result *Result) (bool, bool, []string) { - if len(o.PatternProperties) == 0 { - return false, false, nil - } - - matched := false - succeededOnce := false - patterns := make([]string, 0, len(o.PatternProperties)) - - schema := pools.poolOfSchemas.BorrowSchema() - defer func() { - pools.poolOfSchemas.RedeemSchema(schema) - }() - - for k := range o.PatternProperties { - re, err := compileRegexp(k) - if err != nil { - continue - } - - match := re.MatchString(key) - if !match { - continue - } - - *schema = o.PatternProperties[k] - patterns = append(patterns, k) - matched = true - validator := newSchemaValidator(schema, o.Root, fmt.Sprintf("%s.%s", o.Path, key), o.KnownFormats, o.Options) - - res := validator.Validate(value) - result.Merge(res) - } - - return matched, succeededOnce, patterns -} - -func (o *objectValidator) redeem() { - pools.poolOfObjectValidators.RedeemValidator(o) -} diff --git a/vendor/github.com/go-openapi/validate/options.go b/vendor/github.com/go-openapi/validate/options.go deleted file mode 100644 index cfe9b0660..000000000 --- a/vendor/github.com/go-openapi/validate/options.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import "sync" - -// Opts specifies validation options for a SpecValidator. -// -// NOTE: other options might be needed, for example a go-swagger specific mode. -type Opts struct { - ContinueOnErrors bool // true: continue reporting errors, even if spec is invalid - - // StrictPathParamUniqueness enables a strict validation of paths that include - // path parameters. When true, it will enforce that for each method, the path - // is unique, regardless of path parameters such that GET:/petstore/{id} and - // GET:/petstore/{pet} anre considered duplicate paths. - // - // Consider disabling if path parameters can include slashes such as - // GET:/v1/{shelve} and GET:/v1/{book}, where the IDs are "shelve/*" and - // /"shelve/*/book/*" respectively. - StrictPathParamUniqueness bool - SkipSchemataResult bool -} - -var ( - defaultOpts = Opts{ - // default is to stop validation on errors - ContinueOnErrors: false, - - // StrictPathParamUniqueness is defaulted to true. This maintains existing - // behavior. - StrictPathParamUniqueness: true, - } - - defaultOptsMutex = &sync.Mutex{} -) - -// SetContinueOnErrors sets global default behavior regarding spec validation errors reporting. -// -// For extended error reporting, you most likely want to set it to true. -// For faster validation, it's better to give up early when a spec is detected as invalid: set it to false (this is the default). -// -// Setting this mode does NOT affect the validation status. -// -// NOTE: this method affects global defaults. It is not suitable for a concurrent usage. -func SetContinueOnErrors(c bool) { - defer defaultOptsMutex.Unlock() - defaultOptsMutex.Lock() - defaultOpts.ContinueOnErrors = c -} diff --git a/vendor/github.com/go-openapi/validate/pools.go b/vendor/github.com/go-openapi/validate/pools.go deleted file mode 100644 index 3ddce4dcc..000000000 --- a/vendor/github.com/go-openapi/validate/pools.go +++ /dev/null @@ -1,366 +0,0 @@ -//go:build !validatedebug - -package validate - -import ( - "sync" - - "github.com/go-openapi/spec" -) - -var pools allPools - -func init() { - resetPools() -} - -func resetPools() { - // NOTE: for testing purpose, we might want to reset pools after calling Validate twice. - // The pool is corrupted in that case: calling Put twice inserts a duplicate in the pool - // and further calls to Get are mishandled. - - pools = allPools{ - poolOfSchemaValidators: schemaValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &SchemaValidator{} - - return s - }, - }, - }, - poolOfObjectValidators: objectValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &objectValidator{} - - return s - }, - }, - }, - poolOfSliceValidators: sliceValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &schemaSliceValidator{} - - return s - }, - }, - }, - poolOfItemsValidators: itemsValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &itemsValidator{} - - return s - }, - }, - }, - poolOfBasicCommonValidators: basicCommonValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &basicCommonValidator{} - - return s - }, - }, - }, - poolOfHeaderValidators: headerValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &HeaderValidator{} - - return s - }, - }, - }, - poolOfParamValidators: paramValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &ParamValidator{} - - return s - }, - }, - }, - poolOfBasicSliceValidators: basicSliceValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &basicSliceValidator{} - - return s - }, - }, - }, - poolOfNumberValidators: numberValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &numberValidator{} - - return s - }, - }, - }, - poolOfStringValidators: stringValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &stringValidator{} - - return s - }, - }, - }, - poolOfSchemaPropsValidators: schemaPropsValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &schemaPropsValidator{} - - return s - }, - }, - }, - poolOfFormatValidators: formatValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &formatValidator{} - - return s - }, - }, - }, - poolOfTypeValidators: typeValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &typeValidator{} - - return s - }, - }, - }, - poolOfSchemas: schemasPool{ - Pool: &sync.Pool{ - New: func() any { - s := &spec.Schema{} - - return s - }, - }, - }, - poolOfResults: resultsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &Result{} - - return s - }, - }, - }, - } -} - -type ( - allPools struct { - // memory pools for all validator objects. - // - // Each pool can be borrowed from and redeemed to. - poolOfSchemaValidators schemaValidatorsPool - poolOfObjectValidators objectValidatorsPool - poolOfSliceValidators sliceValidatorsPool - poolOfItemsValidators itemsValidatorsPool - poolOfBasicCommonValidators basicCommonValidatorsPool - poolOfHeaderValidators headerValidatorsPool - poolOfParamValidators paramValidatorsPool - poolOfBasicSliceValidators basicSliceValidatorsPool - poolOfNumberValidators numberValidatorsPool - poolOfStringValidators stringValidatorsPool - poolOfSchemaPropsValidators schemaPropsValidatorsPool - poolOfFormatValidators formatValidatorsPool - poolOfTypeValidators typeValidatorsPool - poolOfSchemas schemasPool - poolOfResults resultsPool - } - - schemaValidatorsPool struct { - *sync.Pool - } - - objectValidatorsPool struct { - *sync.Pool - } - - sliceValidatorsPool struct { - *sync.Pool - } - - itemsValidatorsPool struct { - *sync.Pool - } - - basicCommonValidatorsPool struct { - *sync.Pool - } - - headerValidatorsPool struct { - *sync.Pool - } - - paramValidatorsPool struct { - *sync.Pool - } - - basicSliceValidatorsPool struct { - *sync.Pool - } - - numberValidatorsPool struct { - *sync.Pool - } - - stringValidatorsPool struct { - *sync.Pool - } - - schemaPropsValidatorsPool struct { - *sync.Pool - } - - formatValidatorsPool struct { - *sync.Pool - } - - typeValidatorsPool struct { - *sync.Pool - } - - schemasPool struct { - *sync.Pool - } - - resultsPool struct { - *sync.Pool - } -) - -func (p schemaValidatorsPool) BorrowValidator() *SchemaValidator { - return p.Get().(*SchemaValidator) -} - -func (p schemaValidatorsPool) RedeemValidator(s *SchemaValidator) { - // NOTE: s might be nil. In that case, Put is a noop. - p.Put(s) -} - -func (p objectValidatorsPool) BorrowValidator() *objectValidator { - return p.Get().(*objectValidator) -} - -func (p objectValidatorsPool) RedeemValidator(s *objectValidator) { - p.Put(s) -} - -func (p sliceValidatorsPool) BorrowValidator() *schemaSliceValidator { - return p.Get().(*schemaSliceValidator) -} - -func (p sliceValidatorsPool) RedeemValidator(s *schemaSliceValidator) { - p.Put(s) -} - -func (p itemsValidatorsPool) BorrowValidator() *itemsValidator { - return p.Get().(*itemsValidator) -} - -func (p itemsValidatorsPool) RedeemValidator(s *itemsValidator) { - p.Put(s) -} - -func (p basicCommonValidatorsPool) BorrowValidator() *basicCommonValidator { - return p.Get().(*basicCommonValidator) -} - -func (p basicCommonValidatorsPool) RedeemValidator(s *basicCommonValidator) { - p.Put(s) -} - -func (p headerValidatorsPool) BorrowValidator() *HeaderValidator { - return p.Get().(*HeaderValidator) -} - -func (p headerValidatorsPool) RedeemValidator(s *HeaderValidator) { - p.Put(s) -} - -func (p paramValidatorsPool) BorrowValidator() *ParamValidator { - return p.Get().(*ParamValidator) -} - -func (p paramValidatorsPool) RedeemValidator(s *ParamValidator) { - p.Put(s) -} - -func (p basicSliceValidatorsPool) BorrowValidator() *basicSliceValidator { - return p.Get().(*basicSliceValidator) -} - -func (p basicSliceValidatorsPool) RedeemValidator(s *basicSliceValidator) { - p.Put(s) -} - -func (p numberValidatorsPool) BorrowValidator() *numberValidator { - return p.Get().(*numberValidator) -} - -func (p numberValidatorsPool) RedeemValidator(s *numberValidator) { - p.Put(s) -} - -func (p stringValidatorsPool) BorrowValidator() *stringValidator { - return p.Get().(*stringValidator) -} - -func (p stringValidatorsPool) RedeemValidator(s *stringValidator) { - p.Put(s) -} - -func (p schemaPropsValidatorsPool) BorrowValidator() *schemaPropsValidator { - return p.Get().(*schemaPropsValidator) -} - -func (p schemaPropsValidatorsPool) RedeemValidator(s *schemaPropsValidator) { - p.Put(s) -} - -func (p formatValidatorsPool) BorrowValidator() *formatValidator { - return p.Get().(*formatValidator) -} - -func (p formatValidatorsPool) RedeemValidator(s *formatValidator) { - p.Put(s) -} - -func (p typeValidatorsPool) BorrowValidator() *typeValidator { - return p.Get().(*typeValidator) -} - -func (p typeValidatorsPool) RedeemValidator(s *typeValidator) { - p.Put(s) -} - -func (p schemasPool) BorrowSchema() *spec.Schema { - return p.Get().(*spec.Schema) -} - -func (p schemasPool) RedeemSchema(s *spec.Schema) { - p.Put(s) -} - -func (p resultsPool) BorrowResult() *Result { - return p.Get().(*Result).cleared() -} - -func (p resultsPool) RedeemResult(s *Result) { - if s == emptyResult { - return - } - p.Put(s) -} diff --git a/vendor/github.com/go-openapi/validate/pools_debug.go b/vendor/github.com/go-openapi/validate/pools_debug.go deleted file mode 100644 index 12949f02a..000000000 --- a/vendor/github.com/go-openapi/validate/pools_debug.go +++ /dev/null @@ -1,1012 +0,0 @@ -//go:build validatedebug - -package validate - -import ( - "fmt" - "runtime" - "sync" - "testing" - - "github.com/go-openapi/spec" -) - -// This version of the pools is to be used for debugging and testing, with build tag "validatedebug". -// -// In this mode, the pools are tracked for allocation and redemption of borrowed objects, so we can -// verify a few behaviors of the validators. The debug pools panic when an invalid usage pattern is detected. - -var pools allPools - -func init() { - resetPools() -} - -func resetPools() { - // NOTE: for testing purpose, we might want to reset pools after calling Validate twice. - // The pool is corrupted in that case: calling Put twice inserts a duplicate in the pool - // and further calls to Get are mishandled. - - pools = allPools{ - poolOfSchemaValidators: schemaValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &SchemaValidator{} - - return s - }, - }, - debugMap: make(map[*SchemaValidator]status), - allocMap: make(map[*SchemaValidator]string), - redeemMap: make(map[*SchemaValidator]string), - }, - poolOfObjectValidators: objectValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &objectValidator{} - - return s - }, - }, - debugMap: make(map[*objectValidator]status), - allocMap: make(map[*objectValidator]string), - redeemMap: make(map[*objectValidator]string), - }, - poolOfSliceValidators: sliceValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &schemaSliceValidator{} - - return s - }, - }, - debugMap: make(map[*schemaSliceValidator]status), - allocMap: make(map[*schemaSliceValidator]string), - redeemMap: make(map[*schemaSliceValidator]string), - }, - poolOfItemsValidators: itemsValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &itemsValidator{} - - return s - }, - }, - debugMap: make(map[*itemsValidator]status), - allocMap: make(map[*itemsValidator]string), - redeemMap: make(map[*itemsValidator]string), - }, - poolOfBasicCommonValidators: basicCommonValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &basicCommonValidator{} - - return s - }, - }, - debugMap: make(map[*basicCommonValidator]status), - allocMap: make(map[*basicCommonValidator]string), - redeemMap: make(map[*basicCommonValidator]string), - }, - poolOfHeaderValidators: headerValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &HeaderValidator{} - - return s - }, - }, - debugMap: make(map[*HeaderValidator]status), - allocMap: make(map[*HeaderValidator]string), - redeemMap: make(map[*HeaderValidator]string), - }, - poolOfParamValidators: paramValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &ParamValidator{} - - return s - }, - }, - debugMap: make(map[*ParamValidator]status), - allocMap: make(map[*ParamValidator]string), - redeemMap: make(map[*ParamValidator]string), - }, - poolOfBasicSliceValidators: basicSliceValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &basicSliceValidator{} - - return s - }, - }, - debugMap: make(map[*basicSliceValidator]status), - allocMap: make(map[*basicSliceValidator]string), - redeemMap: make(map[*basicSliceValidator]string), - }, - poolOfNumberValidators: numberValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &numberValidator{} - - return s - }, - }, - debugMap: make(map[*numberValidator]status), - allocMap: make(map[*numberValidator]string), - redeemMap: make(map[*numberValidator]string), - }, - poolOfStringValidators: stringValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &stringValidator{} - - return s - }, - }, - debugMap: make(map[*stringValidator]status), - allocMap: make(map[*stringValidator]string), - redeemMap: make(map[*stringValidator]string), - }, - poolOfSchemaPropsValidators: schemaPropsValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &schemaPropsValidator{} - - return s - }, - }, - debugMap: make(map[*schemaPropsValidator]status), - allocMap: make(map[*schemaPropsValidator]string), - redeemMap: make(map[*schemaPropsValidator]string), - }, - poolOfFormatValidators: formatValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &formatValidator{} - - return s - }, - }, - debugMap: make(map[*formatValidator]status), - allocMap: make(map[*formatValidator]string), - redeemMap: make(map[*formatValidator]string), - }, - poolOfTypeValidators: typeValidatorsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &typeValidator{} - - return s - }, - }, - debugMap: make(map[*typeValidator]status), - allocMap: make(map[*typeValidator]string), - redeemMap: make(map[*typeValidator]string), - }, - poolOfSchemas: schemasPool{ - Pool: &sync.Pool{ - New: func() any { - s := &spec.Schema{} - - return s - }, - }, - debugMap: make(map[*spec.Schema]status), - allocMap: make(map[*spec.Schema]string), - redeemMap: make(map[*spec.Schema]string), - }, - poolOfResults: resultsPool{ - Pool: &sync.Pool{ - New: func() any { - s := &Result{} - - return s - }, - }, - debugMap: make(map[*Result]status), - allocMap: make(map[*Result]string), - redeemMap: make(map[*Result]string), - }, - } -} - -const ( - statusFresh status = iota + 1 - statusRecycled - statusRedeemed -) - -func (s status) String() string { - switch s { - case statusFresh: - return "fresh" - case statusRecycled: - return "recycled" - case statusRedeemed: - return "redeemed" - default: - panic(fmt.Errorf("invalid status: %d", s)) - } -} - -type ( - // Debug - status uint8 - - allPools struct { - // memory pools for all validator objects. - // - // Each pool can be borrowed from and redeemed to. - poolOfSchemaValidators schemaValidatorsPool - poolOfObjectValidators objectValidatorsPool - poolOfSliceValidators sliceValidatorsPool - poolOfItemsValidators itemsValidatorsPool - poolOfBasicCommonValidators basicCommonValidatorsPool - poolOfHeaderValidators headerValidatorsPool - poolOfParamValidators paramValidatorsPool - poolOfBasicSliceValidators basicSliceValidatorsPool - poolOfNumberValidators numberValidatorsPool - poolOfStringValidators stringValidatorsPool - poolOfSchemaPropsValidators schemaPropsValidatorsPool - poolOfFormatValidators formatValidatorsPool - poolOfTypeValidators typeValidatorsPool - poolOfSchemas schemasPool - poolOfResults resultsPool - } - - schemaValidatorsPool struct { - *sync.Pool - debugMap map[*SchemaValidator]status - allocMap map[*SchemaValidator]string - redeemMap map[*SchemaValidator]string - mx sync.Mutex - } - - objectValidatorsPool struct { - *sync.Pool - debugMap map[*objectValidator]status - allocMap map[*objectValidator]string - redeemMap map[*objectValidator]string - mx sync.Mutex - } - - sliceValidatorsPool struct { - *sync.Pool - debugMap map[*schemaSliceValidator]status - allocMap map[*schemaSliceValidator]string - redeemMap map[*schemaSliceValidator]string - mx sync.Mutex - } - - itemsValidatorsPool struct { - *sync.Pool - debugMap map[*itemsValidator]status - allocMap map[*itemsValidator]string - redeemMap map[*itemsValidator]string - mx sync.Mutex - } - - basicCommonValidatorsPool struct { - *sync.Pool - debugMap map[*basicCommonValidator]status - allocMap map[*basicCommonValidator]string - redeemMap map[*basicCommonValidator]string - mx sync.Mutex - } - - headerValidatorsPool struct { - *sync.Pool - debugMap map[*HeaderValidator]status - allocMap map[*HeaderValidator]string - redeemMap map[*HeaderValidator]string - mx sync.Mutex - } - - paramValidatorsPool struct { - *sync.Pool - debugMap map[*ParamValidator]status - allocMap map[*ParamValidator]string - redeemMap map[*ParamValidator]string - mx sync.Mutex - } - - basicSliceValidatorsPool struct { - *sync.Pool - debugMap map[*basicSliceValidator]status - allocMap map[*basicSliceValidator]string - redeemMap map[*basicSliceValidator]string - mx sync.Mutex - } - - numberValidatorsPool struct { - *sync.Pool - debugMap map[*numberValidator]status - allocMap map[*numberValidator]string - redeemMap map[*numberValidator]string - mx sync.Mutex - } - - stringValidatorsPool struct { - *sync.Pool - debugMap map[*stringValidator]status - allocMap map[*stringValidator]string - redeemMap map[*stringValidator]string - mx sync.Mutex - } - - schemaPropsValidatorsPool struct { - *sync.Pool - debugMap map[*schemaPropsValidator]status - allocMap map[*schemaPropsValidator]string - redeemMap map[*schemaPropsValidator]string - mx sync.Mutex - } - - formatValidatorsPool struct { - *sync.Pool - debugMap map[*formatValidator]status - allocMap map[*formatValidator]string - redeemMap map[*formatValidator]string - mx sync.Mutex - } - - typeValidatorsPool struct { - *sync.Pool - debugMap map[*typeValidator]status - allocMap map[*typeValidator]string - redeemMap map[*typeValidator]string - mx sync.Mutex - } - - schemasPool struct { - *sync.Pool - debugMap map[*spec.Schema]status - allocMap map[*spec.Schema]string - redeemMap map[*spec.Schema]string - mx sync.Mutex - } - - resultsPool struct { - *sync.Pool - debugMap map[*Result]status - allocMap map[*Result]string - redeemMap map[*Result]string - mx sync.Mutex - } -) - -func (p *schemaValidatorsPool) BorrowValidator() *SchemaValidator { - s := p.Get().(*SchemaValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled schema should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *schemaValidatorsPool) RedeemValidator(s *SchemaValidator) { - // NOTE: s might be nil. In that case, Put is a noop. - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed schema should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed schema should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *objectValidatorsPool) BorrowValidator() *objectValidator { - s := p.Get().(*objectValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled object should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *objectValidatorsPool) RedeemValidator(s *objectValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed object should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed object should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *sliceValidatorsPool) BorrowValidator() *schemaSliceValidator { - s := p.Get().(*schemaSliceValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled schemaSliceValidator should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *sliceValidatorsPool) RedeemValidator(s *schemaSliceValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed schemaSliceValidator should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed schemaSliceValidator should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *itemsValidatorsPool) BorrowValidator() *itemsValidator { - s := p.Get().(*itemsValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled itemsValidator should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *itemsValidatorsPool) RedeemValidator(s *itemsValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed itemsValidator should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed itemsValidator should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *basicCommonValidatorsPool) BorrowValidator() *basicCommonValidator { - s := p.Get().(*basicCommonValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled basicCommonValidator should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *basicCommonValidatorsPool) RedeemValidator(s *basicCommonValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed basicCommonValidator should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed basicCommonValidator should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *headerValidatorsPool) BorrowValidator() *HeaderValidator { - s := p.Get().(*HeaderValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled HeaderValidator should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *headerValidatorsPool) RedeemValidator(s *HeaderValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed header should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed header should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *paramValidatorsPool) BorrowValidator() *ParamValidator { - s := p.Get().(*ParamValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled param should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *paramValidatorsPool) RedeemValidator(s *ParamValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed param should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed param should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *basicSliceValidatorsPool) BorrowValidator() *basicSliceValidator { - s := p.Get().(*basicSliceValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled basicSliceValidator should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *basicSliceValidatorsPool) RedeemValidator(s *basicSliceValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed basicSliceValidator should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed basicSliceValidator should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *numberValidatorsPool) BorrowValidator() *numberValidator { - s := p.Get().(*numberValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled number should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *numberValidatorsPool) RedeemValidator(s *numberValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed number should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed number should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *stringValidatorsPool) BorrowValidator() *stringValidator { - s := p.Get().(*stringValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled string should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *stringValidatorsPool) RedeemValidator(s *stringValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed string should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed string should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *schemaPropsValidatorsPool) BorrowValidator() *schemaPropsValidator { - s := p.Get().(*schemaPropsValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled param should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *schemaPropsValidatorsPool) RedeemValidator(s *schemaPropsValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed schemaProps should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed schemaProps should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *formatValidatorsPool) BorrowValidator() *formatValidator { - s := p.Get().(*formatValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled format should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *formatValidatorsPool) RedeemValidator(s *formatValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed format should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed format should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *typeValidatorsPool) BorrowValidator() *typeValidator { - s := p.Get().(*typeValidator) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled type should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *typeValidatorsPool) RedeemValidator(s *typeValidator) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed type should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic(fmt.Errorf("redeemed type should have been allocated from a fresh or recycled pointer. Got status %s, already redeamed at: %s", x, p.redeemMap[s])) - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *schemasPool) BorrowSchema() *spec.Schema { - s := p.Get().(*spec.Schema) - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled spec.Schema should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *schemasPool) RedeemSchema(s *spec.Schema) { - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed spec.Schema should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed spec.Schema should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *resultsPool) BorrowResult() *Result { - s := p.Get().(*Result).cleared() - - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - p.debugMap[s] = statusFresh - } else { - if x != statusRedeemed { - panic("recycled result should have been redeemed") - } - p.debugMap[s] = statusRecycled - } - p.allocMap[s] = caller() - - return s -} - -func (p *resultsPool) RedeemResult(s *Result) { - if s == emptyResult { - if len(s.Errors) > 0 || len(s.Warnings) > 0 { - panic("empty result should not mutate") - } - return - } - p.mx.Lock() - defer p.mx.Unlock() - x, ok := p.debugMap[s] - if !ok { - panic("redeemed Result should have been allocated") - } - if x != statusRecycled && x != statusFresh { - panic("redeemed Result should have been allocated from a fresh or recycled pointer") - } - p.debugMap[s] = statusRedeemed - p.redeemMap[s] = caller() - p.Put(s) -} - -func (p *allPools) allIsRedeemed(t testing.TB) bool { - outcome := true - for k, v := range p.poolOfSchemaValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("schemaValidator should be redeemed. Allocated by: %s", p.poolOfSchemaValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfObjectValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("objectValidator should be redeemed. Allocated by: %s", p.poolOfObjectValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfSliceValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("sliceValidator should be redeemed. Allocated by: %s", p.poolOfSliceValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfItemsValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("itemsValidator should be redeemed. Allocated by: %s", p.poolOfItemsValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfBasicCommonValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("basicCommonValidator should be redeemed. Allocated by: %s", p.poolOfBasicCommonValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfHeaderValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("headerValidator should be redeemed. Allocated by: %s", p.poolOfHeaderValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfParamValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("paramValidator should be redeemed. Allocated by: %s", p.poolOfParamValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfBasicSliceValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("basicSliceValidator should be redeemed. Allocated by: %s", p.poolOfBasicSliceValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfNumberValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("numberValidator should be redeemed. Allocated by: %s", p.poolOfNumberValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfStringValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("stringValidator should be redeemed. Allocated by: %s", p.poolOfStringValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfSchemaPropsValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("schemaPropsValidator should be redeemed. Allocated by: %s", p.poolOfSchemaPropsValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfFormatValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("formatValidator should be redeemed. Allocated by: %s", p.poolOfFormatValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfTypeValidators.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("typeValidator should be redeemed. Allocated by: %s", p.poolOfTypeValidators.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfSchemas.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("schemas should be redeemed. Allocated by: %s", p.poolOfSchemas.allocMap[k]) - outcome = false - } - for k, v := range p.poolOfResults.debugMap { - if v == statusRedeemed { - continue - } - t.Logf("result should be redeemed. Allocated by: %s", p.poolOfResults.allocMap[k]) - outcome = false - } - - return outcome -} - -func caller() string { - pc, _, _, _ := runtime.Caller(3) //nolint:dogsled - from, line := runtime.FuncForPC(pc).FileLine(pc) - - return fmt.Sprintf("%s:%d", from, line) -} diff --git a/vendor/github.com/go-openapi/validate/result.go b/vendor/github.com/go-openapi/validate/result.go deleted file mode 100644 index c80804a93..000000000 --- a/vendor/github.com/go-openapi/validate/result.go +++ /dev/null @@ -1,563 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - stderrors "errors" - "reflect" - "strings" - - "github.com/go-openapi/errors" - "github.com/go-openapi/spec" -) - -var emptyResult = &Result{MatchCount: 1} - -// Result represents a validation result set, composed of -// errors and warnings. -// -// It is used to keep track of all detected errors and warnings during -// the validation of a specification. -// -// Matchcount is used to determine -// which errors are relevant in the case of AnyOf, OneOf -// schema validation. Results from the validation branch -// with most matches get eventually selected. -// -// TODO: keep path of key originating the error -type Result struct { - Errors []error - Warnings []error - MatchCount int - - // the object data - data interface{} - - // Schemata for the root object - rootObjectSchemata schemata - // Schemata for object fields - fieldSchemata []fieldSchemata - // Schemata for slice items - itemSchemata []itemSchemata - - cachedFieldSchemata map[FieldKey][]*spec.Schema - cachedItemSchemata map[ItemKey][]*spec.Schema - - wantsRedeemOnMerge bool -} - -// FieldKey is a pair of an object and a field, usable as a key for a map. -type FieldKey struct { - object reflect.Value // actually a map[string]interface{}, but the latter cannot be a key - field string -} - -// ItemKey is a pair of a slice and an index, usable as a key for a map. -type ItemKey struct { - slice reflect.Value // actually a []interface{}, but the latter cannot be a key - index int -} - -// NewFieldKey returns a pair of an object and field usable as a key of a map. -func NewFieldKey(obj map[string]interface{}, field string) FieldKey { - return FieldKey{object: reflect.ValueOf(obj), field: field} -} - -// Object returns the underlying object of this key. -func (fk *FieldKey) Object() map[string]interface{} { - return fk.object.Interface().(map[string]interface{}) -} - -// Field returns the underlying field of this key. -func (fk *FieldKey) Field() string { - return fk.field -} - -// NewItemKey returns a pair of a slice and index usable as a key of a map. -func NewItemKey(slice interface{}, i int) ItemKey { - return ItemKey{slice: reflect.ValueOf(slice), index: i} -} - -// Slice returns the underlying slice of this key. -func (ik *ItemKey) Slice() []interface{} { - return ik.slice.Interface().([]interface{}) -} - -// Index returns the underlying index of this key. -func (ik *ItemKey) Index() int { - return ik.index -} - -type fieldSchemata struct { - obj map[string]interface{} - field string - schemata schemata -} - -type itemSchemata struct { - slice reflect.Value - index int - schemata schemata -} - -// Merge merges this result with the other one(s), preserving match counts etc. -func (r *Result) Merge(others ...*Result) *Result { - for _, other := range others { - if other == nil { - continue - } - r.mergeWithoutRootSchemata(other) - r.rootObjectSchemata.Append(other.rootObjectSchemata) - if other.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(other) - } - } - return r -} - -// Data returns the original data object used for validation. Mutating this renders -// the result invalid. -func (r *Result) Data() interface{} { - return r.data -} - -// RootObjectSchemata returns the schemata which apply to the root object. -func (r *Result) RootObjectSchemata() []*spec.Schema { - return r.rootObjectSchemata.Slice() -} - -// FieldSchemata returns the schemata which apply to fields in objects. -func (r *Result) FieldSchemata() map[FieldKey][]*spec.Schema { - if r.cachedFieldSchemata != nil { - return r.cachedFieldSchemata - } - - ret := make(map[FieldKey][]*spec.Schema, len(r.fieldSchemata)) - for _, fs := range r.fieldSchemata { - key := NewFieldKey(fs.obj, fs.field) - if fs.schemata.one != nil { - ret[key] = append(ret[key], fs.schemata.one) - } else if len(fs.schemata.multiple) > 0 { - ret[key] = append(ret[key], fs.schemata.multiple...) - } - } - r.cachedFieldSchemata = ret - - return ret -} - -// ItemSchemata returns the schemata which apply to items in slices. -func (r *Result) ItemSchemata() map[ItemKey][]*spec.Schema { - if r.cachedItemSchemata != nil { - return r.cachedItemSchemata - } - - ret := make(map[ItemKey][]*spec.Schema, len(r.itemSchemata)) - for _, ss := range r.itemSchemata { - key := NewItemKey(ss.slice, ss.index) - if ss.schemata.one != nil { - ret[key] = append(ret[key], ss.schemata.one) - } else if len(ss.schemata.multiple) > 0 { - ret[key] = append(ret[key], ss.schemata.multiple...) - } - } - r.cachedItemSchemata = ret - return ret -} - -func (r *Result) resetCaches() { - r.cachedFieldSchemata = nil - r.cachedItemSchemata = nil -} - -// mergeForField merges other into r, assigning other's root schemata to the given Object and field name. -// -//nolint:unparam -func (r *Result) mergeForField(obj map[string]interface{}, field string, other *Result) *Result { - if other == nil { - return r - } - r.mergeWithoutRootSchemata(other) - - if other.rootObjectSchemata.Len() > 0 { - if r.fieldSchemata == nil { - r.fieldSchemata = make([]fieldSchemata, len(obj)) - } - // clone other schemata, as other is about to be redeemed to the pool - r.fieldSchemata = append(r.fieldSchemata, fieldSchemata{ - obj: obj, - field: field, - schemata: other.rootObjectSchemata.Clone(), - }) - } - if other.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(other) - } - - return r -} - -// mergeForSlice merges other into r, assigning other's root schemata to the given slice and index. -// -//nolint:unparam -func (r *Result) mergeForSlice(slice reflect.Value, i int, other *Result) *Result { - if other == nil { - return r - } - r.mergeWithoutRootSchemata(other) - - if other.rootObjectSchemata.Len() > 0 { - if r.itemSchemata == nil { - r.itemSchemata = make([]itemSchemata, slice.Len()) - } - // clone other schemata, as other is about to be redeemed to the pool - r.itemSchemata = append(r.itemSchemata, itemSchemata{ - slice: slice, - index: i, - schemata: other.rootObjectSchemata.Clone(), - }) - } - - if other.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(other) - } - - return r -} - -// addRootObjectSchemata adds the given schemata for the root object of the result. -// -// Since the slice schemata might be reused, it is shallow-cloned before saving it into the result. -func (r *Result) addRootObjectSchemata(s *spec.Schema) { - clone := *s - r.rootObjectSchemata.Append(schemata{one: &clone}) -} - -// addPropertySchemata adds the given schemata for the object and field. -// -// Since the slice schemata might be reused, it is shallow-cloned before saving it into the result. -func (r *Result) addPropertySchemata(obj map[string]interface{}, fld string, schema *spec.Schema) { - if r.fieldSchemata == nil { - r.fieldSchemata = make([]fieldSchemata, 0, len(obj)) - } - clone := *schema - r.fieldSchemata = append(r.fieldSchemata, fieldSchemata{obj: obj, field: fld, schemata: schemata{one: &clone}}) -} - -/* -// addSliceSchemata adds the given schemata for the slice and index. -// The slice schemata might be reused. I.e. do not modify it after being added to a result. -func (r *Result) addSliceSchemata(slice reflect.Value, i int, schema *spec.Schema) { - if r.itemSchemata == nil { - r.itemSchemata = make([]itemSchemata, 0, slice.Len()) - } - r.itemSchemata = append(r.itemSchemata, itemSchemata{slice: slice, index: i, schemata: schemata{one: schema}}) -} -*/ - -// mergeWithoutRootSchemata merges other into r, ignoring the rootObject schemata. -func (r *Result) mergeWithoutRootSchemata(other *Result) { - r.resetCaches() - r.AddErrors(other.Errors...) - r.AddWarnings(other.Warnings...) - r.MatchCount += other.MatchCount - - if other.fieldSchemata != nil { - if r.fieldSchemata == nil { - r.fieldSchemata = make([]fieldSchemata, 0, len(other.fieldSchemata)) - } - for _, field := range other.fieldSchemata { - field.schemata = field.schemata.Clone() - r.fieldSchemata = append(r.fieldSchemata, field) - } - } - - if other.itemSchemata != nil { - if r.itemSchemata == nil { - r.itemSchemata = make([]itemSchemata, 0, len(other.itemSchemata)) - } - for _, field := range other.itemSchemata { - field.schemata = field.schemata.Clone() - r.itemSchemata = append(r.itemSchemata, field) - } - } -} - -// MergeAsErrors merges this result with the other one(s), preserving match counts etc. -// -// Warnings from input are merged as Errors in the returned merged Result. -func (r *Result) MergeAsErrors(others ...*Result) *Result { - for _, other := range others { - if other != nil { - r.resetCaches() - r.AddErrors(other.Errors...) - r.AddErrors(other.Warnings...) - r.MatchCount += other.MatchCount - if other.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(other) - } - } - } - return r -} - -// MergeAsWarnings merges this result with the other one(s), preserving match counts etc. -// -// Errors from input are merged as Warnings in the returned merged Result. -func (r *Result) MergeAsWarnings(others ...*Result) *Result { - for _, other := range others { - if other != nil { - r.resetCaches() - r.AddWarnings(other.Errors...) - r.AddWarnings(other.Warnings...) - r.MatchCount += other.MatchCount - if other.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(other) - } - } - } - return r -} - -// AddErrors adds errors to this validation result (if not already reported). -// -// Since the same check may be passed several times while exploring the -// spec structure (via $ref, ...) reported messages are kept -// unique. -func (r *Result) AddErrors(errors ...error) { - for _, e := range errors { - found := false - if e != nil { - for _, isReported := range r.Errors { - if e.Error() == isReported.Error() { - found = true - break - } - } - if !found { - r.Errors = append(r.Errors, e) - } - } - } -} - -// AddWarnings adds warnings to this validation result (if not already reported). -func (r *Result) AddWarnings(warnings ...error) { - for _, e := range warnings { - found := false - if e != nil { - for _, isReported := range r.Warnings { - if e.Error() == isReported.Error() { - found = true - break - } - } - if !found { - r.Warnings = append(r.Warnings, e) - } - } - } -} - -func (r *Result) keepRelevantErrors() *Result { - // TODO: this one is going to disapear... - // keepRelevantErrors strips a result from standard errors and keeps - // the ones which are supposedly more accurate. - // - // The original result remains unaffected (creates a new instance of Result). - // This method is used to work around the "matchCount" filter which would otherwise - // strip our result from some accurate error reporting from lower level validators. - // - // NOTE: this implementation with a placeholder (IMPORTANT!) is neither clean nor - // very efficient. On the other hand, relying on go-openapi/errors to manipulate - // codes would require to change a lot here. So, for the moment, let's go with - // placeholders. - strippedErrors := []error{} - for _, e := range r.Errors { - if strings.HasPrefix(e.Error(), "IMPORTANT!") { - strippedErrors = append(strippedErrors, stderrors.New(strings.TrimPrefix(e.Error(), "IMPORTANT!"))) - } - } - strippedWarnings := []error{} - for _, e := range r.Warnings { - if strings.HasPrefix(e.Error(), "IMPORTANT!") { - strippedWarnings = append(strippedWarnings, stderrors.New(strings.TrimPrefix(e.Error(), "IMPORTANT!"))) - } - } - var strippedResult *Result - if r.wantsRedeemOnMerge { - strippedResult = pools.poolOfResults.BorrowResult() - } else { - strippedResult = new(Result) - } - strippedResult.Errors = strippedErrors - strippedResult.Warnings = strippedWarnings - return strippedResult -} - -// IsValid returns true when this result is valid. -// -// Returns true on a nil *Result. -func (r *Result) IsValid() bool { - if r == nil { - return true - } - return len(r.Errors) == 0 -} - -// HasErrors returns true when this result is invalid. -// -// Returns false on a nil *Result. -func (r *Result) HasErrors() bool { - if r == nil { - return false - } - return !r.IsValid() -} - -// HasWarnings returns true when this result contains warnings. -// -// Returns false on a nil *Result. -func (r *Result) HasWarnings() bool { - if r == nil { - return false - } - return len(r.Warnings) > 0 -} - -// HasErrorsOrWarnings returns true when this result contains -// either errors or warnings. -// -// Returns false on a nil *Result. -func (r *Result) HasErrorsOrWarnings() bool { - if r == nil { - return false - } - return len(r.Errors) > 0 || len(r.Warnings) > 0 -} - -// Inc increments the match count -func (r *Result) Inc() { - r.MatchCount++ -} - -// AsError renders this result as an error interface -// -// TODO: reporting / pretty print with path ordered and indented -func (r *Result) AsError() error { - if r.IsValid() { - return nil - } - return errors.CompositeValidationError(r.Errors...) -} - -func (r *Result) cleared() *Result { - // clear the Result to be reusable. Keep allocated capacity. - r.Errors = r.Errors[:0] - r.Warnings = r.Warnings[:0] - r.MatchCount = 0 - r.data = nil - r.rootObjectSchemata.one = nil - r.rootObjectSchemata.multiple = r.rootObjectSchemata.multiple[:0] - r.fieldSchemata = r.fieldSchemata[:0] - r.itemSchemata = r.itemSchemata[:0] - for k := range r.cachedFieldSchemata { - delete(r.cachedFieldSchemata, k) - } - for k := range r.cachedItemSchemata { - delete(r.cachedItemSchemata, k) - } - r.wantsRedeemOnMerge = true // mark this result as eligible for redeem when merged into another - - return r -} - -// schemata is an arbitrary number of schemata. It does a distinction between zero, -// one and many schemata to avoid slice allocations. -type schemata struct { - // one is set if there is exactly one schema. In that case multiple must be nil. - one *spec.Schema - // multiple is an arbitrary number of schemas. If it is set, one must be nil. - multiple []*spec.Schema -} - -func (s *schemata) Len() int { - if s.one != nil { - return 1 - } - return len(s.multiple) -} - -func (s *schemata) Slice() []*spec.Schema { - if s == nil { - return nil - } - if s.one != nil { - return []*spec.Schema{s.one} - } - return s.multiple -} - -// appendSchemata appends the schemata in other to s. It mutates s in-place. -func (s *schemata) Append(other schemata) { - if other.one == nil && len(other.multiple) == 0 { - return - } - if s.one == nil && len(s.multiple) == 0 { - *s = other - return - } - - if s.one != nil { - if other.one != nil { - s.multiple = []*spec.Schema{s.one, other.one} - } else { - t := make([]*spec.Schema, 0, 1+len(other.multiple)) - s.multiple = append(append(t, s.one), other.multiple...) - } - s.one = nil - } else { - if other.one != nil { - s.multiple = append(s.multiple, other.one) - } else { - if cap(s.multiple) >= len(s.multiple)+len(other.multiple) { - s.multiple = append(s.multiple, other.multiple...) - } else { - t := make([]*spec.Schema, 0, len(s.multiple)+len(other.multiple)) - s.multiple = append(append(t, s.multiple...), other.multiple...) - } - } - } -} - -func (s schemata) Clone() schemata { - var clone schemata - - if s.one != nil { - clone.one = new(spec.Schema) - *clone.one = *s.one - } - - if len(s.multiple) > 0 { - clone.multiple = make([]*spec.Schema, len(s.multiple)) - for idx := 0; idx < len(s.multiple); idx++ { - sp := new(spec.Schema) - *sp = *s.multiple[idx] - clone.multiple[idx] = sp - } - } - - return clone -} diff --git a/vendor/github.com/go-openapi/validate/rexp.go b/vendor/github.com/go-openapi/validate/rexp.go deleted file mode 100644 index 76de03e1f..000000000 --- a/vendor/github.com/go-openapi/validate/rexp.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - re "regexp" - "sync" - "sync/atomic" -) - -// Cache for compiled regular expressions -var ( - cacheMutex = &sync.Mutex{} - reDict = atomic.Value{} // map[string]*re.Regexp -) - -func compileRegexp(pattern string) (*re.Regexp, error) { - if cache, ok := reDict.Load().(map[string]*re.Regexp); ok { - if r := cache[pattern]; r != nil { - return r, nil - } - } - - r, err := re.Compile(pattern) - if err != nil { - return nil, err - } - cacheRegexp(r) - return r, nil -} - -func mustCompileRegexp(pattern string) *re.Regexp { - if cache, ok := reDict.Load().(map[string]*re.Regexp); ok { - if r := cache[pattern]; r != nil { - return r - } - } - - r := re.MustCompile(pattern) - cacheRegexp(r) - return r -} - -func cacheRegexp(r *re.Regexp) { - cacheMutex.Lock() - defer cacheMutex.Unlock() - - if cache, ok := reDict.Load().(map[string]*re.Regexp); !ok || cache[r.String()] == nil { - newCache := map[string]*re.Regexp{ - r.String(): r, - } - - for k, v := range cache { - newCache[k] = v - } - - reDict.Store(newCache) - } -} diff --git a/vendor/github.com/go-openapi/validate/schema.go b/vendor/github.com/go-openapi/validate/schema.go deleted file mode 100644 index db65264fd..000000000 --- a/vendor/github.com/go-openapi/validate/schema.go +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "encoding/json" - "reflect" - - "github.com/go-openapi/errors" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" -) - -// SchemaValidator validates data against a JSON schema -type SchemaValidator struct { - Path string - in string - Schema *spec.Schema - validators [8]valueValidator - Root interface{} - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions -} - -// AgainstSchema validates the specified data against the provided schema, using a registry of supported formats. -// -// When no pre-parsed *spec.Schema structure is provided, it uses a JSON schema as default. See example. -func AgainstSchema(schema *spec.Schema, data interface{}, formats strfmt.Registry, options ...Option) error { - res := NewSchemaValidator(schema, nil, "", formats, - append(options, WithRecycleValidators(true), withRecycleResults(true))..., - ).Validate(data) - defer func() { - pools.poolOfResults.RedeemResult(res) - }() - - if res.HasErrors() { - return errors.CompositeValidationError(res.Errors...) - } - - return nil -} - -// NewSchemaValidator creates a new schema validator. -// -// Panics if the provided schema is invalid. -func NewSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string, formats strfmt.Registry, options ...Option) *SchemaValidator { - opts := new(SchemaValidatorOptions) - for _, o := range options { - o(opts) - } - - return newSchemaValidator(schema, rootSchema, root, formats, opts) -} - -func newSchemaValidator(schema *spec.Schema, rootSchema interface{}, root string, formats strfmt.Registry, opts *SchemaValidatorOptions) *SchemaValidator { - if schema == nil { - return nil - } - - if rootSchema == nil { - rootSchema = schema - } - - if schema.ID != "" || schema.Ref.String() != "" || schema.Ref.IsRoot() { - err := spec.ExpandSchema(schema, rootSchema, nil) - if err != nil { - msg := invalidSchemaProvidedMsg(err).Error() - panic(msg) - } - } - - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var s *SchemaValidator - if opts.recycleValidators { - s = pools.poolOfSchemaValidators.BorrowValidator() - } else { - s = new(SchemaValidator) - } - - s.Path = root - s.in = "body" - s.Schema = schema - s.Root = rootSchema - s.Options = opts - s.KnownFormats = formats - - s.validators = [8]valueValidator{ - s.typeValidator(), - s.schemaPropsValidator(), - s.stringValidator(), - s.formatValidator(), - s.numberValidator(), - s.sliceValidator(), - s.commonValidator(), - s.objectValidator(), - } - - return s -} - -// SetPath sets the path for this schema valdiator -func (s *SchemaValidator) SetPath(path string) { - s.Path = path -} - -// Applies returns true when this schema validator applies -func (s *SchemaValidator) Applies(source interface{}, _ reflect.Kind) bool { - _, ok := source.(*spec.Schema) - return ok -} - -// Validate validates the data against the schema -func (s *SchemaValidator) Validate(data interface{}) *Result { - if s == nil { - return emptyResult - } - - if s.Options.recycleValidators { - defer func() { - s.redeemChildren() - s.redeem() // one-time use validator - }() - } - - var result *Result - if s.Options.recycleResult { - result = pools.poolOfResults.BorrowResult() - result.data = data - } else { - result = &Result{data: data} - } - - if s.Schema != nil && !s.Options.skipSchemataResult { - result.addRootObjectSchemata(s.Schema) - } - - if data == nil { - // early exit with minimal validation - result.Merge(s.validators[0].Validate(data)) // type validator - result.Merge(s.validators[6].Validate(data)) // common validator - - if s.Options.recycleValidators { - s.validators[0] = nil - s.validators[6] = nil - } - - return result - } - - tpe := reflect.TypeOf(data) - kind := tpe.Kind() - for kind == reflect.Ptr { - tpe = tpe.Elem() - kind = tpe.Kind() - } - d := data - - if kind == reflect.Struct { - // NOTE: since reflect retrieves the true nature of types - // this means that all strfmt types passed here (e.g. strfmt.Datetime, etc..) - // are converted here to strings, and structs are systematically converted - // to map[string]interface{}. - d = swag.ToDynamicJSON(data) - } - - // TODO: this part should be handed over to type validator - // Handle special case of json.Number data (number marshalled as string) - isnumber := s.Schema.Type.Contains(numberType) || s.Schema.Type.Contains(integerType) - if num, ok := data.(json.Number); ok && isnumber { - if s.Schema.Type.Contains(integerType) { // avoid lossy conversion - in, erri := num.Int64() - if erri != nil { - result.AddErrors(invalidTypeConversionMsg(s.Path, erri)) - result.Inc() - - return result - } - d = in - } else { - nf, errf := num.Float64() - if errf != nil { - result.AddErrors(invalidTypeConversionMsg(s.Path, errf)) - result.Inc() - - return result - } - d = nf - } - - tpe = reflect.TypeOf(d) - kind = tpe.Kind() - } - - for idx, v := range s.validators { - if !v.Applies(s.Schema, kind) { - if s.Options.recycleValidators { - // Validate won't be called, so relinquish this validator - if redeemableChildren, ok := v.(interface{ redeemChildren() }); ok { - redeemableChildren.redeemChildren() - } - if redeemable, ok := v.(interface{ redeem() }); ok { - redeemable.redeem() - } - s.validators[idx] = nil // prevents further (unsafe) usage - } - - continue - } - - result.Merge(v.Validate(d)) - if s.Options.recycleValidators { - s.validators[idx] = nil // prevents further (unsafe) usage - } - result.Inc() - } - result.Inc() - - return result -} - -func (s *SchemaValidator) typeValidator() valueValidator { - return newTypeValidator( - s.Path, - s.in, - s.Schema.Type, - s.Schema.Nullable, - s.Schema.Format, - s.Options, - ) -} - -func (s *SchemaValidator) commonValidator() valueValidator { - return newBasicCommonValidator( - s.Path, - s.in, - s.Schema.Default, - s.Schema.Enum, - s.Options, - ) -} - -func (s *SchemaValidator) sliceValidator() valueValidator { - return newSliceValidator( - s.Path, - s.in, - s.Schema.MaxItems, - s.Schema.MinItems, - s.Schema.UniqueItems, - s.Schema.AdditionalItems, - s.Schema.Items, - s.Root, - s.KnownFormats, - s.Options, - ) -} - -func (s *SchemaValidator) numberValidator() valueValidator { - return newNumberValidator( - s.Path, - s.in, - s.Schema.Default, - s.Schema.MultipleOf, - s.Schema.Maximum, - s.Schema.ExclusiveMaximum, - s.Schema.Minimum, - s.Schema.ExclusiveMinimum, - "", - "", - s.Options, - ) -} - -func (s *SchemaValidator) stringValidator() valueValidator { - return newStringValidator( - s.Path, - s.in, - nil, - false, - false, - s.Schema.MaxLength, - s.Schema.MinLength, - s.Schema.Pattern, - s.Options, - ) -} - -func (s *SchemaValidator) formatValidator() valueValidator { - return newFormatValidator( - s.Path, - s.in, - s.Schema.Format, - s.KnownFormats, - s.Options, - ) -} - -func (s *SchemaValidator) schemaPropsValidator() valueValidator { - sch := s.Schema - return newSchemaPropsValidator( - s.Path, s.in, sch.AllOf, sch.OneOf, sch.AnyOf, sch.Not, sch.Dependencies, s.Root, s.KnownFormats, - s.Options, - ) -} - -func (s *SchemaValidator) objectValidator() valueValidator { - return newObjectValidator( - s.Path, - s.in, - s.Schema.MaxProperties, - s.Schema.MinProperties, - s.Schema.Required, - s.Schema.Properties, - s.Schema.AdditionalProperties, - s.Schema.PatternProperties, - s.Root, - s.KnownFormats, - s.Options, - ) -} - -func (s *SchemaValidator) redeem() { - pools.poolOfSchemaValidators.RedeemValidator(s) -} - -func (s *SchemaValidator) redeemChildren() { - for i, validator := range s.validators { - if validator == nil { - continue - } - if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok { - redeemableChildren.redeemChildren() - } - if redeemable, ok := validator.(interface{ redeem() }); ok { - redeemable.redeem() - } - s.validators[i] = nil // free up allocated children if not in pool - } -} diff --git a/vendor/github.com/go-openapi/validate/schema_messages.go b/vendor/github.com/go-openapi/validate/schema_messages.go deleted file mode 100644 index 786e2e355..000000000 --- a/vendor/github.com/go-openapi/validate/schema_messages.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "github.com/go-openapi/errors" -) - -// Error messages related to schema validation and returned as results. -const ( - // ArrayDoesNotAllowAdditionalItemsError when an additionalItems construct is not verified by the array values provided. - // - // TODO: should move to package go-openapi/errors - ArrayDoesNotAllowAdditionalItemsError = "array doesn't allow for additional items" - - // HasDependencyError indicates that a dependencies construct was not verified - HasDependencyError = "%q has a dependency on %s" - - // InvalidSchemaProvidedError indicates that the schema provided to validate a value cannot be properly compiled - InvalidSchemaProvidedError = "Invalid schema provided to SchemaValidator: %v" - - // InvalidTypeConversionError indicates that a numerical conversion for the given type could not be carried on - InvalidTypeConversionError = "invalid type conversion in %s: %v " - - // MustValidateAtLeastOneSchemaError indicates that in a AnyOf construct, none of the schema constraints specified were verified - MustValidateAtLeastOneSchemaError = "%q must validate at least one schema (anyOf)" - - // MustValidateOnlyOneSchemaError indicates that in a OneOf construct, either none of the schema constraints specified were verified, or several were - MustValidateOnlyOneSchemaError = "%q must validate one and only one schema (oneOf). %s" - - // MustValidateAllSchemasError indicates that in a AllOf construct, at least one of the schema constraints specified were not verified - // - // TODO: punctuation in message - MustValidateAllSchemasError = "%q must validate all the schemas (allOf)%s" - - // MustNotValidateSchemaError indicates that in a Not construct, the schema constraint specified was verified - MustNotValidateSchemaError = "%q must not validate the schema (not)" -) - -// Warning messages related to schema validation and returned as results -const () - -func invalidSchemaProvidedMsg(err error) errors.Error { - return errors.New(InternalErrorCode, InvalidSchemaProvidedError, err) -} -func invalidTypeConversionMsg(path string, err error) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidTypeConversionError, path, err) -} -func mustValidateOnlyOneSchemaMsg(path, additionalMsg string) errors.Error { - return errors.New(errors.CompositeErrorCode, MustValidateOnlyOneSchemaError, path, additionalMsg) -} -func mustValidateAtLeastOneSchemaMsg(path string) errors.Error { - return errors.New(errors.CompositeErrorCode, MustValidateAtLeastOneSchemaError, path) -} -func mustValidateAllSchemasMsg(path, additionalMsg string) errors.Error { - return errors.New(errors.CompositeErrorCode, MustValidateAllSchemasError, path, additionalMsg) -} -func mustNotValidatechemaMsg(path string) errors.Error { - return errors.New(errors.CompositeErrorCode, MustNotValidateSchemaError, path) -} -func hasADependencyMsg(path, depkey string) errors.Error { - return errors.New(errors.CompositeErrorCode, HasDependencyError, path, depkey) -} -func arrayDoesNotAllowAdditionalItemsMsg() errors.Error { - return errors.New(errors.CompositeErrorCode, ArrayDoesNotAllowAdditionalItemsError) -} diff --git a/vendor/github.com/go-openapi/validate/schema_option.go b/vendor/github.com/go-openapi/validate/schema_option.go deleted file mode 100644 index 65eeebeaa..000000000 --- a/vendor/github.com/go-openapi/validate/schema_option.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -// SchemaValidatorOptions defines optional rules for schema validation -type SchemaValidatorOptions struct { - EnableObjectArrayTypeCheck bool - EnableArrayMustHaveItemsCheck bool - recycleValidators bool - recycleResult bool - skipSchemataResult bool -} - -// Option sets optional rules for schema validation -type Option func(*SchemaValidatorOptions) - -// EnableObjectArrayTypeCheck activates the swagger rule: an items must be in type: array -func EnableObjectArrayTypeCheck(enable bool) Option { - return func(svo *SchemaValidatorOptions) { - svo.EnableObjectArrayTypeCheck = enable - } -} - -// EnableArrayMustHaveItemsCheck activates the swagger rule: an array must have items defined -func EnableArrayMustHaveItemsCheck(enable bool) Option { - return func(svo *SchemaValidatorOptions) { - svo.EnableArrayMustHaveItemsCheck = enable - } -} - -// SwaggerSchema activates swagger schema validation rules -func SwaggerSchema(enable bool) Option { - return func(svo *SchemaValidatorOptions) { - svo.EnableObjectArrayTypeCheck = enable - svo.EnableArrayMustHaveItemsCheck = enable - } -} - -// WithRecycleValidators saves memory allocations and makes validators -// available for a single use of Validate() only. -// -// When a validator is recycled, called MUST not call the Validate() method twice. -func WithRecycleValidators(enable bool) Option { - return func(svo *SchemaValidatorOptions) { - svo.recycleValidators = enable - } -} - -func withRecycleResults(enable bool) Option { - return func(svo *SchemaValidatorOptions) { - svo.recycleResult = enable - } -} - -// WithSkipSchemataResult skips the deep audit payload stored in validation Result -func WithSkipSchemataResult(enable bool) Option { - return func(svo *SchemaValidatorOptions) { - svo.skipSchemataResult = enable - } -} - -// Options returns the current set of options -func (svo SchemaValidatorOptions) Options() []Option { - return []Option{ - EnableObjectArrayTypeCheck(svo.EnableObjectArrayTypeCheck), - EnableArrayMustHaveItemsCheck(svo.EnableArrayMustHaveItemsCheck), - WithRecycleValidators(svo.recycleValidators), - withRecycleResults(svo.recycleResult), - WithSkipSchemataResult(svo.skipSchemataResult), - } -} diff --git a/vendor/github.com/go-openapi/validate/schema_props.go b/vendor/github.com/go-openapi/validate/schema_props.go deleted file mode 100644 index 1ca379244..000000000 --- a/vendor/github.com/go-openapi/validate/schema_props.go +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "fmt" - "reflect" - - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" -) - -type schemaPropsValidator struct { - Path string - In string - AllOf []spec.Schema - OneOf []spec.Schema - AnyOf []spec.Schema - Not *spec.Schema - Dependencies spec.Dependencies - anyOfValidators []*SchemaValidator - allOfValidators []*SchemaValidator - oneOfValidators []*SchemaValidator - notValidator *SchemaValidator - Root interface{} - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions -} - -func (s *schemaPropsValidator) SetPath(path string) { - s.Path = path -} - -func newSchemaPropsValidator( - path string, in string, allOf, oneOf, anyOf []spec.Schema, not *spec.Schema, deps spec.Dependencies, root interface{}, formats strfmt.Registry, - opts *SchemaValidatorOptions) *schemaPropsValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - anyValidators := make([]*SchemaValidator, 0, len(anyOf)) - for i := range anyOf { - anyValidators = append(anyValidators, newSchemaValidator(&anyOf[i], root, path, formats, opts)) - } - allValidators := make([]*SchemaValidator, 0, len(allOf)) - for i := range allOf { - allValidators = append(allValidators, newSchemaValidator(&allOf[i], root, path, formats, opts)) - } - oneValidators := make([]*SchemaValidator, 0, len(oneOf)) - for i := range oneOf { - oneValidators = append(oneValidators, newSchemaValidator(&oneOf[i], root, path, formats, opts)) - } - - var notValidator *SchemaValidator - if not != nil { - notValidator = newSchemaValidator(not, root, path, formats, opts) - } - - var s *schemaPropsValidator - if opts.recycleValidators { - s = pools.poolOfSchemaPropsValidators.BorrowValidator() - } else { - s = new(schemaPropsValidator) - } - - s.Path = path - s.In = in - s.AllOf = allOf - s.OneOf = oneOf - s.AnyOf = anyOf - s.Not = not - s.Dependencies = deps - s.anyOfValidators = anyValidators - s.allOfValidators = allValidators - s.oneOfValidators = oneValidators - s.notValidator = notValidator - s.Root = root - s.KnownFormats = formats - s.Options = opts - - return s -} - -func (s *schemaPropsValidator) Applies(source interface{}, _ reflect.Kind) bool { - _, isSchema := source.(*spec.Schema) - return isSchema -} - -func (s *schemaPropsValidator) Validate(data interface{}) *Result { - var mainResult *Result - if s.Options.recycleResult { - mainResult = pools.poolOfResults.BorrowResult() - } else { - mainResult = new(Result) - } - - // Intermediary error results - - // IMPORTANT! messages from underlying validators - var keepResultAnyOf, keepResultOneOf, keepResultAllOf *Result - - if s.Options.recycleValidators { - defer func() { - s.redeemChildren() - s.redeem() - - // results are redeemed when merged - }() - } - - if len(s.anyOfValidators) > 0 { - keepResultAnyOf = pools.poolOfResults.BorrowResult() - s.validateAnyOf(data, mainResult, keepResultAnyOf) - } - - if len(s.oneOfValidators) > 0 { - keepResultOneOf = pools.poolOfResults.BorrowResult() - s.validateOneOf(data, mainResult, keepResultOneOf) - } - - if len(s.allOfValidators) > 0 { - keepResultAllOf = pools.poolOfResults.BorrowResult() - s.validateAllOf(data, mainResult, keepResultAllOf) - } - - if s.notValidator != nil { - s.validateNot(data, mainResult) - } - - if s.Dependencies != nil && len(s.Dependencies) > 0 && reflect.TypeOf(data).Kind() == reflect.Map { - s.validateDependencies(data, mainResult) - } - - mainResult.Inc() - - // In the end we retain best failures for schema validation - // plus, if any, composite errors which may explain special cases (tagged as IMPORTANT!). - return mainResult.Merge(keepResultAllOf, keepResultOneOf, keepResultAnyOf) -} - -func (s *schemaPropsValidator) validateAnyOf(data interface{}, mainResult, keepResultAnyOf *Result) { - // Validates at least one in anyOf schemas - var bestFailures *Result - - for i, anyOfSchema := range s.anyOfValidators { - result := anyOfSchema.Validate(data) - if s.Options.recycleValidators { - s.anyOfValidators[i] = nil - } - // We keep inner IMPORTANT! errors no matter what MatchCount tells us - keepResultAnyOf.Merge(result.keepRelevantErrors()) // merges (and redeems) a new instance of Result - - if result.IsValid() { - if bestFailures != nil && bestFailures.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(bestFailures) - } - - _ = keepResultAnyOf.cleared() - mainResult.Merge(result) - - return - } - - // MatchCount is used to select errors from the schema with most positive checks - if bestFailures == nil || result.MatchCount > bestFailures.MatchCount { - if bestFailures != nil && bestFailures.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(bestFailures) - } - bestFailures = result - - continue - } - - if result.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(result) // this result is ditched - } - } - - mainResult.AddErrors(mustValidateAtLeastOneSchemaMsg(s.Path)) - mainResult.Merge(bestFailures) -} - -func (s *schemaPropsValidator) validateOneOf(data interface{}, mainResult, keepResultOneOf *Result) { - // Validates exactly one in oneOf schemas - var ( - firstSuccess, bestFailures *Result - validated int - ) - - for i, oneOfSchema := range s.oneOfValidators { - result := oneOfSchema.Validate(data) - if s.Options.recycleValidators { - s.oneOfValidators[i] = nil - } - - // We keep inner IMPORTANT! errors no matter what MatchCount tells us - keepResultOneOf.Merge(result.keepRelevantErrors()) // merges (and redeems) a new instance of Result - - if result.IsValid() { - validated++ - _ = keepResultOneOf.cleared() - - if firstSuccess == nil { - firstSuccess = result - } else if result.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(result) // this result is ditched - } - - continue - } - - // MatchCount is used to select errors from the schema with most positive checks - if validated == 0 && (bestFailures == nil || result.MatchCount > bestFailures.MatchCount) { - if bestFailures != nil && bestFailures.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(bestFailures) - } - bestFailures = result - } else if result.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(result) // this result is ditched - } - } - - switch validated { - case 0: - mainResult.AddErrors(mustValidateOnlyOneSchemaMsg(s.Path, "Found none valid")) - mainResult.Merge(bestFailures) - // firstSucess necessarily nil - case 1: - mainResult.Merge(firstSuccess) - if bestFailures != nil && bestFailures.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(bestFailures) - } - default: - mainResult.AddErrors(mustValidateOnlyOneSchemaMsg(s.Path, fmt.Sprintf("Found %d valid alternatives", validated))) - mainResult.Merge(bestFailures) - if firstSuccess != nil && firstSuccess.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(firstSuccess) - } - } -} - -func (s *schemaPropsValidator) validateAllOf(data interface{}, mainResult, keepResultAllOf *Result) { - // Validates all of allOf schemas - var validated int - - for i, allOfSchema := range s.allOfValidators { - result := allOfSchema.Validate(data) - if s.Options.recycleValidators { - s.allOfValidators[i] = nil - } - // We keep inner IMPORTANT! errors no matter what MatchCount tells us - keepResultAllOf.Merge(result.keepRelevantErrors()) - if result.IsValid() { - validated++ - } - mainResult.Merge(result) - } - - switch validated { - case 0: - mainResult.AddErrors(mustValidateAllSchemasMsg(s.Path, ". None validated")) - case len(s.allOfValidators): - default: - mainResult.AddErrors(mustValidateAllSchemasMsg(s.Path, "")) - } -} - -func (s *schemaPropsValidator) validateNot(data interface{}, mainResult *Result) { - result := s.notValidator.Validate(data) - if s.Options.recycleValidators { - s.notValidator = nil - } - // We keep inner IMPORTANT! errors no matter what MatchCount tells us - if result.IsValid() { - mainResult.AddErrors(mustNotValidatechemaMsg(s.Path)) - } - if result.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(result) // this result is ditched - } -} - -func (s *schemaPropsValidator) validateDependencies(data interface{}, mainResult *Result) { - val := data.(map[string]interface{}) - for key := range val { - dep, ok := s.Dependencies[key] - if !ok { - continue - } - - if dep.Schema != nil { - mainResult.Merge( - newSchemaValidator(dep.Schema, s.Root, s.Path+"."+key, s.KnownFormats, s.Options).Validate(data), - ) - continue - } - - if len(dep.Property) > 0 { - for _, depKey := range dep.Property { - if _, ok := val[depKey]; !ok { - mainResult.AddErrors(hasADependencyMsg(s.Path, depKey)) - } - } - } - } -} - -func (s *schemaPropsValidator) redeem() { - pools.poolOfSchemaPropsValidators.RedeemValidator(s) -} - -func (s *schemaPropsValidator) redeemChildren() { - for _, v := range s.anyOfValidators { - if v == nil { - continue - } - v.redeemChildren() - v.redeem() - } - s.anyOfValidators = nil - - for _, v := range s.allOfValidators { - if v == nil { - continue - } - v.redeemChildren() - v.redeem() - } - s.allOfValidators = nil - - for _, v := range s.oneOfValidators { - if v == nil { - continue - } - v.redeemChildren() - v.redeem() - } - s.oneOfValidators = nil - - if s.notValidator != nil { - s.notValidator.redeemChildren() - s.notValidator.redeem() - s.notValidator = nil - } -} diff --git a/vendor/github.com/go-openapi/validate/slice_validator.go b/vendor/github.com/go-openapi/validate/slice_validator.go deleted file mode 100644 index 13bb02087..000000000 --- a/vendor/github.com/go-openapi/validate/slice_validator.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "fmt" - "reflect" - - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" -) - -type schemaSliceValidator struct { - Path string - In string - MaxItems *int64 - MinItems *int64 - UniqueItems bool - AdditionalItems *spec.SchemaOrBool - Items *spec.SchemaOrArray - Root interface{} - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions -} - -func newSliceValidator(path, in string, - maxItems, minItems *int64, uniqueItems bool, - additionalItems *spec.SchemaOrBool, items *spec.SchemaOrArray, - root interface{}, formats strfmt.Registry, opts *SchemaValidatorOptions) *schemaSliceValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var v *schemaSliceValidator - if opts.recycleValidators { - v = pools.poolOfSliceValidators.BorrowValidator() - } else { - v = new(schemaSliceValidator) - } - - v.Path = path - v.In = in - v.MaxItems = maxItems - v.MinItems = minItems - v.UniqueItems = uniqueItems - v.AdditionalItems = additionalItems - v.Items = items - v.Root = root - v.KnownFormats = formats - v.Options = opts - - return v -} - -func (s *schemaSliceValidator) SetPath(path string) { - s.Path = path -} - -func (s *schemaSliceValidator) Applies(source interface{}, kind reflect.Kind) bool { - _, ok := source.(*spec.Schema) - r := ok && kind == reflect.Slice - return r -} - -func (s *schemaSliceValidator) Validate(data interface{}) *Result { - if s.Options.recycleValidators { - defer func() { - s.redeem() - }() - } - - var result *Result - if s.Options.recycleResult { - result = pools.poolOfResults.BorrowResult() - } else { - result = new(Result) - } - if data == nil { - return result - } - val := reflect.ValueOf(data) - size := val.Len() - - if s.Items != nil && s.Items.Schema != nil { - for i := 0; i < size; i++ { - validator := newSchemaValidator(s.Items.Schema, s.Root, s.Path, s.KnownFormats, s.Options) - validator.SetPath(fmt.Sprintf("%s.%d", s.Path, i)) - value := val.Index(i) - result.mergeForSlice(val, i, validator.Validate(value.Interface())) - } - } - - itemsSize := 0 - if s.Items != nil && len(s.Items.Schemas) > 0 { - itemsSize = len(s.Items.Schemas) - for i := 0; i < itemsSize; i++ { - if size <= i { - break - } - - validator := newSchemaValidator(&s.Items.Schemas[i], s.Root, fmt.Sprintf("%s.%d", s.Path, i), s.KnownFormats, s.Options) - result.mergeForSlice(val, i, validator.Validate(val.Index(i).Interface())) - } - } - if s.AdditionalItems != nil && itemsSize < size { - if s.Items != nil && len(s.Items.Schemas) > 0 && !s.AdditionalItems.Allows { - result.AddErrors(arrayDoesNotAllowAdditionalItemsMsg()) - } - if s.AdditionalItems.Schema != nil { - for i := itemsSize; i < size-itemsSize+1; i++ { - validator := newSchemaValidator(s.AdditionalItems.Schema, s.Root, fmt.Sprintf("%s.%d", s.Path, i), s.KnownFormats, s.Options) - result.mergeForSlice(val, i, validator.Validate(val.Index(i).Interface())) - } - } - } - - if s.MinItems != nil { - if err := MinItems(s.Path, s.In, int64(size), *s.MinItems); err != nil { - result.AddErrors(err) - } - } - if s.MaxItems != nil { - if err := MaxItems(s.Path, s.In, int64(size), *s.MaxItems); err != nil { - result.AddErrors(err) - } - } - if s.UniqueItems { - if err := UniqueItems(s.Path, s.In, val.Interface()); err != nil { - result.AddErrors(err) - } - } - result.Inc() - return result -} - -func (s *schemaSliceValidator) redeem() { - pools.poolOfSliceValidators.RedeemValidator(s) -} diff --git a/vendor/github.com/go-openapi/validate/spec.go b/vendor/github.com/go-openapi/validate/spec.go deleted file mode 100644 index 965452566..000000000 --- a/vendor/github.com/go-openapi/validate/spec.go +++ /dev/null @@ -1,852 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "bytes" - "encoding/gob" - "encoding/json" - "fmt" - "sort" - "strings" - - "github.com/go-openapi/analysis" - "github.com/go-openapi/errors" - "github.com/go-openapi/jsonpointer" - "github.com/go-openapi/loads" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" -) - -// Spec validates an OpenAPI 2.0 specification document. -// -// Returns an error flattening in a single standard error, all validation messages. -// -// - TODO: $ref should not have siblings -// - TODO: make sure documentation reflects all checks and warnings -// - TODO: check on discriminators -// - TODO: explicit message on unsupported keywords (better than "forbidden property"...) -// - TODO: full list of unresolved refs -// - TODO: validate numeric constraints (issue#581): this should be handled like defaults and examples -// - TODO: option to determine if we validate for go-swagger or in a more general context -// - TODO: check on required properties to support anyOf, allOf, oneOf -// -// NOTE: SecurityScopes are maps: no need to check uniqueness -func Spec(doc *loads.Document, formats strfmt.Registry) error { - errs, _ /*warns*/ := NewSpecValidator(doc.Schema(), formats).Validate(doc) - if errs.HasErrors() { - return errors.CompositeValidationError(errs.Errors...) - } - return nil -} - -// SpecValidator validates a swagger 2.0 spec -type SpecValidator struct { - schema *spec.Schema // swagger 2.0 schema - spec *loads.Document - analyzer *analysis.Spec - expanded *loads.Document - KnownFormats strfmt.Registry - Options Opts // validation options - schemaOptions *SchemaValidatorOptions -} - -// NewSpecValidator creates a new swagger spec validator instance -func NewSpecValidator(schema *spec.Schema, formats strfmt.Registry) *SpecValidator { - // schema options that apply to all called validators - schemaOptions := new(SchemaValidatorOptions) - for _, o := range []Option{ - SwaggerSchema(true), - WithRecycleValidators(true), - // withRecycleResults(true), - } { - o(schemaOptions) - } - - return &SpecValidator{ - schema: schema, - KnownFormats: formats, - Options: defaultOpts, - schemaOptions: schemaOptions, - } -} - -// Validate validates the swagger spec -func (s *SpecValidator) Validate(data interface{}) (*Result, *Result) { - s.schemaOptions.skipSchemataResult = s.Options.SkipSchemataResult - var sd *loads.Document - errs, warnings := new(Result), new(Result) - - if v, ok := data.(*loads.Document); ok { - sd = v - } - if sd == nil { - errs.AddErrors(invalidDocumentMsg()) - return errs, warnings // no point in continuing - } - s.spec = sd - s.analyzer = analysis.New(sd.Spec()) - - // Raw spec unmarshalling errors - var obj interface{} - if err := json.Unmarshal(sd.Raw(), &obj); err != nil { - // NOTE: under normal conditions, the *load.Document has been already unmarshalled - // So this one is just a paranoid check on the behavior of the spec package - panic(InvalidDocumentError) - } - - defer func() { - // errs holds all errors and warnings, - // warnings only warnings - errs.MergeAsWarnings(warnings) - warnings.AddErrors(errs.Warnings...) - }() - - // Swagger schema validator - schv := newSchemaValidator(s.schema, nil, "", s.KnownFormats, s.schemaOptions) - errs.Merge(schv.Validate(obj)) // error - - // There may be a point in continuing to try and determine more accurate errors - if !s.Options.ContinueOnErrors && errs.HasErrors() { - return errs, warnings // no point in continuing - } - - errs.Merge(s.validateReferencesValid()) // error - - // There may be a point in continuing to try and determine more accurate errors - if !s.Options.ContinueOnErrors && errs.HasErrors() { - return errs, warnings // no point in continuing - } - - errs.Merge(s.validateDuplicateOperationIDs()) - errs.Merge(s.validateDuplicatePropertyNames()) // error - - errs.Merge(s.validateParameters()) // error - - errs.Merge(s.validateItems()) // error - - - // Properties in required definition MUST validate their schema - // Properties SHOULD NOT be declared as both required and readOnly (warning) - errs.Merge(s.validateRequiredDefinitions()) // error and warning - - // There may be a point in continuing to try and determine more accurate errors - if !s.Options.ContinueOnErrors && errs.HasErrors() { - return errs, warnings // no point in continuing - } - - // Values provided as default MUST validate their schema - df := &defaultValidator{SpecValidator: s, schemaOptions: s.schemaOptions} - errs.Merge(df.Validate()) - - // Values provided as examples MUST validate their schema - // Value provided as examples in a response without schema generate a warning - // Known limitations: examples in responses for mime type not application/json are ignored (warning) - ex := &exampleValidator{SpecValidator: s, schemaOptions: s.schemaOptions} - errs.Merge(ex.Validate()) - - errs.Merge(s.validateNonEmptyPathParamNames()) - - // errs.Merge(s.validateRefNoSibling()) // warning only - errs.Merge(s.validateReferenced()) // warning only - - return errs, warnings -} - -func (s *SpecValidator) validateNonEmptyPathParamNames() *Result { - res := pools.poolOfResults.BorrowResult() - if s.spec.Spec().Paths == nil { - // There is no Paths object: error - res.AddErrors(noValidPathMsg()) - - return res - } - - if s.spec.Spec().Paths.Paths == nil { - // Paths may be empty: warning - res.AddWarnings(noValidPathMsg()) - - return res - } - - for k := range s.spec.Spec().Paths.Paths { - if strings.Contains(k, "{}") { - res.AddErrors(emptyPathParameterMsg(k)) - } - } - - return res -} - -func (s *SpecValidator) validateDuplicateOperationIDs() *Result { - // OperationID, if specified, must be unique across the board - var analyzer *analysis.Spec - if s.expanded != nil { - // $ref are valid: we can analyze operations on an expanded spec - analyzer = analysis.New(s.expanded.Spec()) - } else { - // fallback on possible incomplete picture because of previous errors - analyzer = s.analyzer - } - res := pools.poolOfResults.BorrowResult() - known := make(map[string]int) - for _, v := range analyzer.OperationIDs() { - if v != "" { - known[v]++ - } - } - for k, v := range known { - if v > 1 { - res.AddErrors(nonUniqueOperationIDMsg(k, v)) - } - } - return res -} - -type dupProp struct { - Name string - Definition string -} - -func (s *SpecValidator) validateDuplicatePropertyNames() *Result { - // definition can't declare a property that's already defined by one of its ancestors - res := pools.poolOfResults.BorrowResult() - for k, sch := range s.spec.Spec().Definitions { - if len(sch.AllOf) == 0 { - continue - } - - knownanc := map[string]struct{}{ - "#/definitions/" + k: {}, - } - - ancs, rec := s.validateCircularAncestry(k, sch, knownanc) - if rec != nil && (rec.HasErrors() || !rec.HasWarnings()) { - res.Merge(rec) - } - if len(ancs) > 0 { - res.AddErrors(circularAncestryDefinitionMsg(k, ancs)) - return res - } - - knowns := make(map[string]struct{}) - dups, rep := s.validateSchemaPropertyNames(k, sch, knowns) - if rep != nil && (rep.HasErrors() || rep.HasWarnings()) { - res.Merge(rep) - } - if len(dups) > 0 { - var pns []string - for _, v := range dups { - pns = append(pns, v.Definition+"."+v.Name) - } - res.AddErrors(duplicatePropertiesMsg(k, pns)) - } - - } - return res -} - -func (s *SpecValidator) resolveRef(ref *spec.Ref) (*spec.Schema, error) { - if s.spec.SpecFilePath() != "" { - return spec.ResolveRefWithBase(s.spec.Spec(), ref, &spec.ExpandOptions{RelativeBase: s.spec.SpecFilePath()}) - } - // NOTE: it looks like with the new spec resolver, this code is now unrecheable - return spec.ResolveRef(s.spec.Spec(), ref) -} - -func (s *SpecValidator) validateSchemaPropertyNames(nm string, sch spec.Schema, knowns map[string]struct{}) ([]dupProp, *Result) { - var dups []dupProp - - schn := nm - schc := &sch - res := pools.poolOfResults.BorrowResult() - - for schc.Ref.String() != "" { - // gather property names - reso, err := s.resolveRef(&schc.Ref) - if err != nil { - errorHelp.addPointerError(res, err, schc.Ref.String(), nm) - return dups, res - } - schc = reso - schn = sch.Ref.String() - } - - if len(schc.AllOf) > 0 { - for _, chld := range schc.AllOf { - dup, rep := s.validateSchemaPropertyNames(schn, chld, knowns) - if rep != nil && (rep.HasErrors() || rep.HasWarnings()) { - res.Merge(rep) - } - dups = append(dups, dup...) - } - return dups, res - } - - for k := range schc.Properties { - _, ok := knowns[k] - if ok { - dups = append(dups, dupProp{Name: k, Definition: schn}) - } else { - knowns[k] = struct{}{} - } - } - - return dups, res -} - -func (s *SpecValidator) validateCircularAncestry(nm string, sch spec.Schema, knowns map[string]struct{}) ([]string, *Result) { - res := pools.poolOfResults.BorrowResult() - - if sch.Ref.String() == "" && len(sch.AllOf) == 0 { // Safeguard. We should not be able to actually get there - return nil, res - } - var ancs []string - - schn := nm - schc := &sch - - for schc.Ref.String() != "" { - reso, err := s.resolveRef(&schc.Ref) - if err != nil { - errorHelp.addPointerError(res, err, schc.Ref.String(), nm) - return ancs, res - } - schc = reso - schn = sch.Ref.String() - } - - if schn != nm && schn != "" { - if _, ok := knowns[schn]; ok { - ancs = append(ancs, schn) - } - knowns[schn] = struct{}{} - - if len(ancs) > 0 { - return ancs, res - } - } - - if len(schc.AllOf) > 0 { - for _, chld := range schc.AllOf { - if chld.Ref.String() != "" || len(chld.AllOf) > 0 { - anc, rec := s.validateCircularAncestry(schn, chld, knowns) - if rec != nil && (rec.HasErrors() || !rec.HasWarnings()) { - res.Merge(rec) - } - ancs = append(ancs, anc...) - if len(ancs) > 0 { - return ancs, res - } - } - } - } - return ancs, res -} - -func (s *SpecValidator) validateItems() *Result { - // validate parameter, items, schema and response objects for presence of item if type is array - res := pools.poolOfResults.BorrowResult() - - for method, pi := range s.analyzer.Operations() { - for path, op := range pi { - for _, param := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) { - - if param.TypeName() == arrayType && param.ItemsTypeName() == "" { - res.AddErrors(arrayInParamRequiresItemsMsg(param.Name, op.ID)) - continue - } - if param.In != swaggerBody { - if param.Items != nil { - items := param.Items - for items.TypeName() == arrayType { - if items.ItemsTypeName() == "" { - res.AddErrors(arrayInParamRequiresItemsMsg(param.Name, op.ID)) - break - } - items = items.Items - } - } - } else { - // In: body - if param.Schema != nil { - res.Merge(s.validateSchemaItems(*param.Schema, fmt.Sprintf("body param %q", param.Name), op.ID)) - } - } - } - - var responses []spec.Response - if op.Responses != nil { - if op.Responses.Default != nil { - responses = append(responses, *op.Responses.Default) - } - if op.Responses.StatusCodeResponses != nil { - for _, v := range op.Responses.StatusCodeResponses { - responses = append(responses, v) - } - } - } - - for _, resp := range responses { - // Response headers with array - for hn, hv := range resp.Headers { - if hv.TypeName() == arrayType && hv.ItemsTypeName() == "" { - res.AddErrors(arrayInHeaderRequiresItemsMsg(hn, op.ID)) - } - } - if resp.Schema != nil { - res.Merge(s.validateSchemaItems(*resp.Schema, "response body", op.ID)) - } - } - } - } - return res -} - -// Verifies constraints on array type -func (s *SpecValidator) validateSchemaItems(schema spec.Schema, prefix, opID string) *Result { - res := pools.poolOfResults.BorrowResult() - if !schema.Type.Contains(arrayType) { - return res - } - - if schema.Items == nil || schema.Items.Len() == 0 { - res.AddErrors(arrayRequiresItemsMsg(prefix, opID)) - return res - } - - if schema.Items.Schema != nil { - schema = *schema.Items.Schema - if _, err := compileRegexp(schema.Pattern); err != nil { - res.AddErrors(invalidItemsPatternMsg(prefix, opID, schema.Pattern)) - } - - res.Merge(s.validateSchemaItems(schema, prefix, opID)) - } - return res -} - -func (s *SpecValidator) validatePathParamPresence(path string, fromPath, fromOperation []string) *Result { - // Each defined operation path parameters must correspond to a named element in the API's path pattern. - // (For example, you cannot have a path parameter named id for the following path /pets/{petId} but you must have a path parameter named petId.) - res := pools.poolOfResults.BorrowResult() - for _, l := range fromPath { - var matched bool - for _, r := range fromOperation { - if l == "{"+r+"}" { - matched = true - break - } - } - if !matched { - res.AddErrors(noParameterInPathMsg(l)) - } - } - - for _, p := range fromOperation { - var matched bool - for _, r := range fromPath { - if "{"+p+"}" == r { - matched = true - break - } - } - if !matched { - res.AddErrors(pathParamNotInPathMsg(path, p)) - } - } - - return res -} - -func (s *SpecValidator) validateReferenced() *Result { - var res Result - res.MergeAsWarnings(s.validateReferencedParameters()) - res.MergeAsWarnings(s.validateReferencedResponses()) - res.MergeAsWarnings(s.validateReferencedDefinitions()) - return &res -} - -func (s *SpecValidator) validateReferencedParameters() *Result { - // Each referenceable definition should have references. - params := s.spec.Spec().Parameters - if len(params) == 0 { - return nil - } - - expected := make(map[string]struct{}) - for k := range params { - expected["#/parameters/"+jsonpointer.Escape(k)] = struct{}{} - } - for _, k := range s.analyzer.AllParameterReferences() { - delete(expected, k) - } - - if len(expected) == 0 { - return nil - } - result := pools.poolOfResults.BorrowResult() - for k := range expected { - result.AddWarnings(unusedParamMsg(k)) - } - return result -} - -func (s *SpecValidator) validateReferencedResponses() *Result { - // Each referenceable definition should have references. - responses := s.spec.Spec().Responses - if len(responses) == 0 { - return nil - } - - expected := make(map[string]struct{}) - for k := range responses { - expected["#/responses/"+jsonpointer.Escape(k)] = struct{}{} - } - for _, k := range s.analyzer.AllResponseReferences() { - delete(expected, k) - } - - if len(expected) == 0 { - return nil - } - result := pools.poolOfResults.BorrowResult() - for k := range expected { - result.AddWarnings(unusedResponseMsg(k)) - } - return result -} - -func (s *SpecValidator) validateReferencedDefinitions() *Result { - // Each referenceable definition must have references. - defs := s.spec.Spec().Definitions - if len(defs) == 0 { - return nil - } - - expected := make(map[string]struct{}) - for k := range defs { - expected["#/definitions/"+jsonpointer.Escape(k)] = struct{}{} - } - for _, k := range s.analyzer.AllDefinitionReferences() { - delete(expected, k) - } - - if len(expected) == 0 { - return nil - } - - result := new(Result) - for k := range expected { - result.AddWarnings(unusedDefinitionMsg(k)) - } - return result -} - -func (s *SpecValidator) validateRequiredDefinitions() *Result { - // Each property listed in the required array must be defined in the properties of the model - res := pools.poolOfResults.BorrowResult() - -DEFINITIONS: - for d, schema := range s.spec.Spec().Definitions { - if schema.Required != nil { // Safeguard - for _, pn := range schema.Required { - red := s.validateRequiredProperties(pn, d, &schema) //#nosec - res.Merge(red) - if !red.IsValid() && !s.Options.ContinueOnErrors { - break DEFINITIONS // there is an error, let's stop that bleeding - } - } - } - } - return res -} - -func (s *SpecValidator) validateRequiredProperties(path, in string, v *spec.Schema) *Result { - // Takes care of recursive property definitions, which may be nested in additionalProperties schemas - res := pools.poolOfResults.BorrowResult() - propertyMatch := false - patternMatch := false - additionalPropertiesMatch := false - isReadOnly := false - - // Regular properties - if _, ok := v.Properties[path]; ok { - propertyMatch = true - isReadOnly = v.Properties[path].ReadOnly - } - - // NOTE: patternProperties are not supported in swagger. Even though, we continue validation here - // We check all defined patterns: if one regexp is invalid, croaks an error - for pp, pv := range v.PatternProperties { - re, err := compileRegexp(pp) - if err != nil { - res.AddErrors(invalidPatternMsg(pp, in)) - } else if re.MatchString(path) { - patternMatch = true - if !propertyMatch { - isReadOnly = pv.ReadOnly - } - } - } - - if !(propertyMatch || patternMatch) { - if v.AdditionalProperties != nil { - if v.AdditionalProperties.Allows && v.AdditionalProperties.Schema == nil { - additionalPropertiesMatch = true - } else if v.AdditionalProperties.Schema != nil { - // additionalProperties as schema are upported in swagger - // recursively validates additionalProperties schema - // TODO : anyOf, allOf, oneOf like in schemaPropsValidator - red := s.validateRequiredProperties(path, in, v.AdditionalProperties.Schema) - if red.IsValid() { - additionalPropertiesMatch = true - if !propertyMatch && !patternMatch { - isReadOnly = v.AdditionalProperties.Schema.ReadOnly - } - } - res.Merge(red) - } - } - } - - if !(propertyMatch || patternMatch || additionalPropertiesMatch) { - res.AddErrors(requiredButNotDefinedMsg(path, in)) - } - - if isReadOnly { - res.AddWarnings(readOnlyAndRequiredMsg(in, path)) - } - return res -} - -func (s *SpecValidator) validateParameters() *Result { - // - for each method, path is unique, regardless of path parameters - // e.g. GET:/petstore/{id}, GET:/petstore/{pet}, GET:/petstore are - // considered duplicate paths, if StrictPathParamUniqueness is enabled. - // - each parameter should have a unique `name` and `type` combination - // - each operation should have only 1 parameter of type body - // - there must be at most 1 parameter in body - // - parameters with pattern property must specify valid patterns - // - $ref in parameters must resolve - // - path param must be required - res := pools.poolOfResults.BorrowResult() - rexGarbledPathSegment := mustCompileRegexp(`.*[{}\s]+.*`) - for method, pi := range s.expandedAnalyzer().Operations() { - methodPaths := make(map[string]map[string]string) - for path, op := range pi { - if s.Options.StrictPathParamUniqueness { - pathToAdd := pathHelp.stripParametersInPath(path) - - // Warn on garbled path afer param stripping - if rexGarbledPathSegment.MatchString(pathToAdd) { - res.AddWarnings(pathStrippedParamGarbledMsg(pathToAdd)) - } - - // Check uniqueness of stripped paths - if _, found := methodPaths[method][pathToAdd]; found { - - // Sort names for stable, testable output - if strings.Compare(path, methodPaths[method][pathToAdd]) < 0 { - res.AddErrors(pathOverlapMsg(path, methodPaths[method][pathToAdd])) - } else { - res.AddErrors(pathOverlapMsg(methodPaths[method][pathToAdd], path)) - } - } else { - if _, found := methodPaths[method]; !found { - methodPaths[method] = map[string]string{} - } - methodPaths[method][pathToAdd] = path // Original non stripped path - - } - } - - var bodyParams []string - var paramNames []string - var hasForm, hasBody bool - - // Check parameters names uniqueness for operation - // TODO: should be done after param expansion - res.Merge(s.checkUniqueParams(path, method, op)) - - // pick the root schema from the swagger specification which describes a parameter - origSchema, ok := s.schema.Definitions["parameter"] - if !ok { - panic("unexpected swagger schema: missing #/definitions/parameter") - } - // clone it once to avoid expanding a global schema (e.g. swagger spec) - paramSchema, err := deepCloneSchema(origSchema) - if err != nil { - panic(fmt.Errorf("can't clone schema: %v", err)) - } - - for _, pr := range paramHelp.safeExpandedParamsFor(path, method, op.ID, res, s) { - // An expanded parameter must validate the Parameter schema (an unexpanded $ref always passes high-level schema validation) - schv := newSchemaValidator(¶mSchema, s.schema, fmt.Sprintf("%s.%s.parameters.%s", path, method, pr.Name), s.KnownFormats, s.schemaOptions) - obj := swag.ToDynamicJSON(pr) - res.Merge(schv.Validate(obj)) - - // Validate pattern regexp for parameters with a Pattern property - if _, err := compileRegexp(pr.Pattern); err != nil { - res.AddErrors(invalidPatternInParamMsg(op.ID, pr.Name, pr.Pattern)) - } - - // There must be at most one parameter in body: list them all - if pr.In == swaggerBody { - bodyParams = append(bodyParams, fmt.Sprintf("%q", pr.Name)) - hasBody = true - } - - if pr.In == "path" { - paramNames = append(paramNames, pr.Name) - // Path declared in path must have the required: true property - if !pr.Required { - res.AddErrors(pathParamRequiredMsg(op.ID, pr.Name)) - } - } - - if pr.In == "formData" { - hasForm = true - } - - if !(pr.Type == numberType || pr.Type == integerType) && - (pr.Maximum != nil || pr.Minimum != nil || pr.MultipleOf != nil) { - // A non-numeric parameter has validation keywords for numeric instances (number and integer) - res.AddWarnings(parameterValidationTypeMismatchMsg(pr.Name, path, pr.Type)) - } - - if !(pr.Type == stringType) && - // A non-string parameter has validation keywords for strings - (pr.MaxLength != nil || pr.MinLength != nil || pr.Pattern != "") { - res.AddWarnings(parameterValidationTypeMismatchMsg(pr.Name, path, pr.Type)) - } - - if !(pr.Type == arrayType) && - // A non-array parameter has validation keywords for arrays - (pr.MaxItems != nil || pr.MinItems != nil || pr.UniqueItems) { - res.AddWarnings(parameterValidationTypeMismatchMsg(pr.Name, path, pr.Type)) - } - } - - // In:formData and In:body are mutually exclusive - if hasBody && hasForm { - res.AddErrors(bothFormDataAndBodyMsg(op.ID)) - } - // There must be at most one body param - // Accurately report situations when more than 1 body param is declared (possibly unnamed) - if len(bodyParams) > 1 { - sort.Strings(bodyParams) - res.AddErrors(multipleBodyParamMsg(op.ID, bodyParams)) - } - - // Check uniqueness of parameters in path - paramsInPath := pathHelp.extractPathParams(path) - for i, p := range paramsInPath { - for j, q := range paramsInPath { - if p == q && i > j { - res.AddErrors(pathParamNotUniqueMsg(path, p, q)) - break - } - } - } - - // Warns about possible malformed params in path - rexGarbledParam := mustCompileRegexp(`{.*[{}\s]+.*}`) - for _, p := range paramsInPath { - if rexGarbledParam.MatchString(p) { - res.AddWarnings(pathParamGarbledMsg(path, p)) - } - } - - // Match params from path vs params from params section - res.Merge(s.validatePathParamPresence(path, paramsInPath, paramNames)) - } - } - return res -} - -func (s *SpecValidator) validateReferencesValid() *Result { - // each reference must point to a valid object - res := pools.poolOfResults.BorrowResult() - for _, r := range s.analyzer.AllRefs() { - if !r.IsValidURI(s.spec.SpecFilePath()) { // Safeguard - spec should always yield a valid URI - res.AddErrors(invalidRefMsg(r.String())) - } - } - if !res.HasErrors() { - // NOTE: with default settings, loads.Document.Expanded() - // stops on first error. Anyhow, the expand option to continue - // on errors fails to report errors at all. - exp, err := s.spec.Expanded() - if err != nil { - res.AddErrors(unresolvedReferencesMsg(err)) - } - s.expanded = exp - } - return res -} - -func (s *SpecValidator) checkUniqueParams(path, method string, op *spec.Operation) *Result { - // Check for duplicate parameters declaration in param section. - // Each parameter should have a unique `name` and `type` combination - // NOTE: this could be factorized in analysis (when constructing the params map) - // However, there are some issues with such a factorization: - // - analysis does not seem to fully expand params - // - param keys may be altered by x-go-name - res := pools.poolOfResults.BorrowResult() - pnames := make(map[string]struct{}) - - if op.Parameters != nil { // Safeguard - for _, ppr := range op.Parameters { - var ok bool - pr, red := paramHelp.resolveParam(path, method, op.ID, &ppr, s) //#nosec - res.Merge(red) - - if pr != nil && pr.Name != "" { // params with empty name does no participate the check - key := fmt.Sprintf("%s#%s", pr.In, pr.Name) - - if _, ok = pnames[key]; ok { - res.AddErrors(duplicateParamNameMsg(pr.In, pr.Name, op.ID)) - } - pnames[key] = struct{}{} - } - } - } - return res -} - -// SetContinueOnErrors sets the ContinueOnErrors option for this validator. -func (s *SpecValidator) SetContinueOnErrors(c bool) { - s.Options.ContinueOnErrors = c -} - -// expandedAnalyzer returns expanded.Analyzer when it is available. -// otherwise just analyzer. -func (s *SpecValidator) expandedAnalyzer() *analysis.Spec { - if s.expanded != nil && s.expanded.Analyzer != nil { - return s.expanded.Analyzer - } - return s.analyzer -} - -func deepCloneSchema(src spec.Schema) (spec.Schema, error) { - var b bytes.Buffer - if err := gob.NewEncoder(&b).Encode(src); err != nil { - return spec.Schema{}, err - } - - var dst spec.Schema - if err := gob.NewDecoder(&b).Decode(&dst); err != nil { - return spec.Schema{}, err - } - - return dst, nil -} diff --git a/vendor/github.com/go-openapi/validate/spec_messages.go b/vendor/github.com/go-openapi/validate/spec_messages.go deleted file mode 100644 index 6d1f0f819..000000000 --- a/vendor/github.com/go-openapi/validate/spec_messages.go +++ /dev/null @@ -1,366 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "net/http" - - "github.com/go-openapi/errors" -) - -// Error messages related to spec validation and returned as results. -const ( - // ArrayRequiresItemsError ... - ArrayRequiresItemsError = "%s for %q is a collection without an element type (array requires items definition)" - - // ArrayInParamRequiresItemsError ... - ArrayInParamRequiresItemsError = "param %q for %q is a collection without an element type (array requires item definition)" - - // ArrayInHeaderRequiresItemsError ... - ArrayInHeaderRequiresItemsError = "header %q for %q is a collection without an element type (array requires items definition)" - - // BothFormDataAndBodyError indicates that an operation specifies both a body and a formData parameter, which is forbidden - BothFormDataAndBodyError = "operation %q has both formData and body parameters. Only one such In: type may be used for a given operation" - - // CannotResolveRefError when a $ref could not be resolved - CannotResolveReferenceError = "could not resolve reference in %s to $ref %s: %v" - - // CircularAncestryDefinitionError ... - CircularAncestryDefinitionError = "definition %q has circular ancestry: %v" - - // DefaultValueDoesNotValidateError results from an invalid default value provided - DefaultValueDoesNotValidateError = "default value for %s in %s does not validate its schema" - - // DefaultValueItemsDoesNotValidateError results from an invalid default value provided for Items - DefaultValueItemsDoesNotValidateError = "default value for %s.items in %s does not validate its schema" - - // DefaultValueHeaderDoesNotValidateError results from an invalid default value provided in header - DefaultValueHeaderDoesNotValidateError = "in operation %q, default value in header %s for %s does not validate its schema" - - // DefaultValueHeaderItemsDoesNotValidateError results from an invalid default value provided in header.items - DefaultValueHeaderItemsDoesNotValidateError = "in operation %q, default value in header.items %s for %s does not validate its schema" - - // DefaultValueInDoesNotValidateError ... - DefaultValueInDoesNotValidateError = "in operation %q, default value in %s does not validate its schema" - - // DuplicateParamNameError ... - DuplicateParamNameError = "duplicate parameter name %q for %q in operation %q" - - // DuplicatePropertiesError ... - DuplicatePropertiesError = "definition %q contains duplicate properties: %v" - - // ExampleValueDoesNotValidateError results from an invalid example value provided - ExampleValueDoesNotValidateError = "example value for %s in %s does not validate its schema" - - // ExampleValueItemsDoesNotValidateError results from an invalid example value provided for Items - ExampleValueItemsDoesNotValidateError = "example value for %s.items in %s does not validate its schema" - - // ExampleValueHeaderDoesNotValidateError results from an invalid example value provided in header - ExampleValueHeaderDoesNotValidateError = "in operation %q, example value in header %s for %s does not validate its schema" - - // ExampleValueHeaderItemsDoesNotValidateError results from an invalid example value provided in header.items - ExampleValueHeaderItemsDoesNotValidateError = "in operation %q, example value in header.items %s for %s does not validate its schema" - - // ExampleValueInDoesNotValidateError ... - ExampleValueInDoesNotValidateError = "in operation %q, example value in %s does not validate its schema" - - // EmptyPathParameterError means that a path parameter was found empty (e.g. "{}") - EmptyPathParameterError = "%q contains an empty path parameter" - - // InvalidDocumentError states that spec validation only processes spec.Document objects - InvalidDocumentError = "spec validator can only validate spec.Document objects" - - // InvalidItemsPatternError indicates an Items definition with invalid pattern - InvalidItemsPatternError = "%s for %q has invalid items pattern: %q" - - // InvalidParameterDefinitionError indicates an error detected on a parameter definition - InvalidParameterDefinitionError = "invalid definition for parameter %s in %s in operation %q" - - // InvalidParameterDefinitionAsSchemaError indicates an error detected on a parameter definition, which was mistaken with a schema definition. - // Most likely, this situation is encountered whenever a $ref has been added as a sibling of the parameter definition. - InvalidParameterDefinitionAsSchemaError = "invalid definition as Schema for parameter %s in %s in operation %q" - - // InvalidPatternError ... - InvalidPatternError = "pattern %q is invalid in %s" - - // InvalidPatternInError indicates an invalid pattern in a schema or items definition - InvalidPatternInError = "%s in %s has invalid pattern: %q" - - // InvalidPatternInHeaderError indicates a header definition with an invalid pattern - InvalidPatternInHeaderError = "in operation %q, header %s for %s has invalid pattern %q: %v" - - // InvalidPatternInParamError ... - InvalidPatternInParamError = "operation %q has invalid pattern in param %q: %q" - - // InvalidReferenceError indicates that a $ref property could not be resolved - InvalidReferenceError = "invalid ref %q" - - // InvalidResponseDefinitionAsSchemaError indicates an error detected on a response definition, which was mistaken with a schema definition. - // Most likely, this situation is encountered whenever a $ref has been added as a sibling of the response definition. - InvalidResponseDefinitionAsSchemaError = "invalid definition as Schema for response %s in %s" - - // MultipleBodyParamError indicates that an operation specifies multiple parameter with in: body - MultipleBodyParamError = "operation %q has more than 1 body param: %v" - - // NonUniqueOperationIDError indicates that the same operationId has been specified several times - NonUniqueOperationIDError = "%q is defined %d times" - - // NoParameterInPathError indicates that a path was found without any parameter - NoParameterInPathError = "path param %q has no parameter definition" - - // NoValidPathErrorOrWarning indicates that no single path could be validated. If Paths is empty, this message is only a warning. - NoValidPathErrorOrWarning = "spec has no valid path defined" - - // NoValidResponseError indicates that no valid response description could be found for an operation - NoValidResponseError = "operation %q has no valid response" - - // PathOverlapError ... - PathOverlapError = "path %s overlaps with %s" - - // PathParamNotInPathError indicates that a parameter specified with in: path was not found in the path specification - PathParamNotInPathError = "path param %q is not present in path %q" - - // PathParamNotUniqueError ... - PathParamNotUniqueError = "params in path %q must be unique: %q conflicts with %q" - - // PathParamNotRequiredError ... - PathParamRequiredError = "in operation %q,path param %q must be declared as required" - - // RefNotAllowedInHeaderError indicates a $ref was found in a header definition, which is not allowed by Swagger - RefNotAllowedInHeaderError = "IMPORTANT!in %q: $ref are not allowed in headers. In context for header %q%s" - - // RequiredButNotDefinedError ... - RequiredButNotDefinedError = "%q is present in required but not defined as property in definition %q" - - // SomeParametersBrokenError indicates that some parameters could not be resolved, which might result in partial checks to be carried on - SomeParametersBrokenError = "some parameters definitions are broken in %q.%s. Cannot carry on full checks on parameters for operation %s" - - // UnresolvedReferencesError indicates that at least one $ref could not be resolved - UnresolvedReferencesError = "some references could not be resolved in spec. First found: %v" -) - -// Warning messages related to spec validation and returned as results -const ( - // ExamplesWithoutSchemaWarning indicates that examples are provided for a response,but not schema to validate the example against - ExamplesWithoutSchemaWarning = "Examples provided without schema in operation %q, %s" - - // ExamplesMimeNotSupportedWarning indicates that examples are provided with a mime type different than application/json, which - // the validator dos not support yetl - ExamplesMimeNotSupportedWarning = "No validation attempt for examples for media types other than application/json, in operation %q, %s" - - // PathParamGarbledWarning ... - PathParamGarbledWarning = "in path %q, param %q contains {,} or white space. Albeit not stricly illegal, this is probably no what you want" - - // ParamValidationTypeMismatch indicates that parameter has validation which does not match its type - ParamValidationTypeMismatch = "validation keywords of parameter %q in path %q don't match its type %s" - - // PathStrippedParamGarbledWarning ... - PathStrippedParamGarbledWarning = "path stripped from path parameters %s contains {,} or white space. This is probably no what you want." - - // ReadOnlyAndRequiredWarning ... - ReadOnlyAndRequiredWarning = "Required property %s in %q should not be marked as both required and readOnly" - - // RefShouldNotHaveSiblingsWarning indicates that a $ref was found with a sibling definition. This results in the $ref taking over its siblings, - // which is most likely not wanted. - RefShouldNotHaveSiblingsWarning = "$ref property should have no sibling in %q.%s" - - // RequiredHasDefaultWarning indicates that a required parameter property should not have a default - RequiredHasDefaultWarning = "%s in %s has a default value and is required as parameter" - - // UnusedDefinitionWarning ... - UnusedDefinitionWarning = "definition %q is not used anywhere" - - // UnusedParamWarning ... - UnusedParamWarning = "parameter %q is not used anywhere" - - // UnusedResponseWarning ... - UnusedResponseWarning = "response %q is not used anywhere" - - InvalidObject = "expected an object in %q.%s" -) - -// Additional error codes -const ( - // InternalErrorCode reports an internal technical error - InternalErrorCode = http.StatusInternalServerError - // NotFoundErrorCode indicates that a resource (e.g. a $ref) could not be found - NotFoundErrorCode = http.StatusNotFound -) - -func invalidDocumentMsg() errors.Error { - return errors.New(InternalErrorCode, InvalidDocumentError) -} -func invalidRefMsg(path string) errors.Error { - return errors.New(NotFoundErrorCode, InvalidReferenceError, path) -} -func unresolvedReferencesMsg(err error) errors.Error { - return errors.New(errors.CompositeErrorCode, UnresolvedReferencesError, err) -} -func noValidPathMsg() errors.Error { - return errors.New(errors.CompositeErrorCode, NoValidPathErrorOrWarning) -} -func emptyPathParameterMsg(path string) errors.Error { - return errors.New(errors.CompositeErrorCode, EmptyPathParameterError, path) -} -func nonUniqueOperationIDMsg(path string, i int) errors.Error { - return errors.New(errors.CompositeErrorCode, NonUniqueOperationIDError, path, i) -} -func circularAncestryDefinitionMsg(path string, args interface{}) errors.Error { - return errors.New(errors.CompositeErrorCode, CircularAncestryDefinitionError, path, args) -} -func duplicatePropertiesMsg(path string, args interface{}) errors.Error { - return errors.New(errors.CompositeErrorCode, DuplicatePropertiesError, path, args) -} -func pathParamNotInPathMsg(path, param string) errors.Error { - return errors.New(errors.CompositeErrorCode, PathParamNotInPathError, param, path) -} -func arrayRequiresItemsMsg(path, operation string) errors.Error { - return errors.New(errors.CompositeErrorCode, ArrayRequiresItemsError, path, operation) -} -func arrayInParamRequiresItemsMsg(path, operation string) errors.Error { - return errors.New(errors.CompositeErrorCode, ArrayInParamRequiresItemsError, path, operation) -} -func arrayInHeaderRequiresItemsMsg(path, operation string) errors.Error { - return errors.New(errors.CompositeErrorCode, ArrayInHeaderRequiresItemsError, path, operation) -} -func invalidItemsPatternMsg(path, operation, pattern string) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidItemsPatternError, path, operation, pattern) -} -func invalidPatternMsg(pattern, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidPatternError, pattern, path) -} -func requiredButNotDefinedMsg(path, definition string) errors.Error { - return errors.New(errors.CompositeErrorCode, RequiredButNotDefinedError, path, definition) -} -func pathParamGarbledMsg(path, param string) errors.Error { - return errors.New(errors.CompositeErrorCode, PathParamGarbledWarning, path, param) -} -func pathStrippedParamGarbledMsg(path string) errors.Error { - return errors.New(errors.CompositeErrorCode, PathStrippedParamGarbledWarning, path) -} -func pathOverlapMsg(path, arg string) errors.Error { - return errors.New(errors.CompositeErrorCode, PathOverlapError, path, arg) -} -func invalidPatternInParamMsg(operation, param, pattern string) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidPatternInParamError, operation, param, pattern) -} -func pathParamRequiredMsg(operation, param string) errors.Error { - return errors.New(errors.CompositeErrorCode, PathParamRequiredError, operation, param) -} -func bothFormDataAndBodyMsg(operation string) errors.Error { - return errors.New(errors.CompositeErrorCode, BothFormDataAndBodyError, operation) -} -func multipleBodyParamMsg(operation string, args interface{}) errors.Error { - return errors.New(errors.CompositeErrorCode, MultipleBodyParamError, operation, args) -} -func pathParamNotUniqueMsg(path, param, arg string) errors.Error { - return errors.New(errors.CompositeErrorCode, PathParamNotUniqueError, path, param, arg) -} -func duplicateParamNameMsg(path, param, operation string) errors.Error { - return errors.New(errors.CompositeErrorCode, DuplicateParamNameError, param, path, operation) -} -func unusedParamMsg(arg string) errors.Error { - return errors.New(errors.CompositeErrorCode, UnusedParamWarning, arg) -} -func unusedDefinitionMsg(arg string) errors.Error { - return errors.New(errors.CompositeErrorCode, UnusedDefinitionWarning, arg) -} -func unusedResponseMsg(arg string) errors.Error { - return errors.New(errors.CompositeErrorCode, UnusedResponseWarning, arg) -} -func readOnlyAndRequiredMsg(path, param string) errors.Error { - return errors.New(errors.CompositeErrorCode, ReadOnlyAndRequiredWarning, param, path) -} -func noParameterInPathMsg(param string) errors.Error { - return errors.New(errors.CompositeErrorCode, NoParameterInPathError, param) -} -func requiredHasDefaultMsg(param, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, RequiredHasDefaultWarning, param, path) -} -func defaultValueDoesNotValidateMsg(param, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, DefaultValueDoesNotValidateError, param, path) -} -func defaultValueItemsDoesNotValidateMsg(param, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, DefaultValueItemsDoesNotValidateError, param, path) -} -func noValidResponseMsg(operation string) errors.Error { - return errors.New(errors.CompositeErrorCode, NoValidResponseError, operation) -} -func defaultValueHeaderDoesNotValidateMsg(operation, header, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, DefaultValueHeaderDoesNotValidateError, operation, header, path) -} -func defaultValueHeaderItemsDoesNotValidateMsg(operation, header, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, DefaultValueHeaderItemsDoesNotValidateError, operation, header, path) -} -func invalidPatternInHeaderMsg(operation, header, path, pattern string, args interface{}) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidPatternInHeaderError, operation, header, path, pattern, args) -} -func invalidPatternInMsg(path, in, pattern string) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidPatternInError, path, in, pattern) -} -func defaultValueInDoesNotValidateMsg(operation, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, DefaultValueInDoesNotValidateError, operation, path) -} -func exampleValueDoesNotValidateMsg(param, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, ExampleValueDoesNotValidateError, param, path) -} -func exampleValueItemsDoesNotValidateMsg(param, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, ExampleValueItemsDoesNotValidateError, param, path) -} -func exampleValueHeaderDoesNotValidateMsg(operation, header, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, ExampleValueHeaderDoesNotValidateError, operation, header, path) -} -func exampleValueHeaderItemsDoesNotValidateMsg(operation, header, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, ExampleValueHeaderItemsDoesNotValidateError, operation, header, path) -} -func exampleValueInDoesNotValidateMsg(operation, path string) errors.Error { - return errors.New(errors.CompositeErrorCode, ExampleValueInDoesNotValidateError, operation, path) -} -func examplesWithoutSchemaMsg(operation, response string) errors.Error { - return errors.New(errors.CompositeErrorCode, ExamplesWithoutSchemaWarning, operation, response) -} -func examplesMimeNotSupportedMsg(operation, response string) errors.Error { - return errors.New(errors.CompositeErrorCode, ExamplesMimeNotSupportedWarning, operation, response) -} -func refNotAllowedInHeaderMsg(path, header, ref string) errors.Error { - return errors.New(errors.CompositeErrorCode, RefNotAllowedInHeaderError, path, header, ref) -} -func cannotResolveRefMsg(path, ref string, err error) errors.Error { - return errors.New(errors.CompositeErrorCode, CannotResolveReferenceError, path, ref, err) -} -func invalidParameterDefinitionMsg(path, method, operationID string) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidParameterDefinitionError, path, method, operationID) -} -func invalidParameterDefinitionAsSchemaMsg(path, method, operationID string) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidParameterDefinitionAsSchemaError, path, method, operationID) -} -func parameterValidationTypeMismatchMsg(param, path, typ string) errors.Error { - return errors.New(errors.CompositeErrorCode, ParamValidationTypeMismatch, param, path, typ) -} -func invalidObjectMsg(path, in string) errors.Error { - return errors.New(errors.CompositeErrorCode, InvalidObject, path, in) -} - -// disabled -// -// func invalidResponseDefinitionAsSchemaMsg(path, method string) errors.Error { -// return errors.New(errors.CompositeErrorCode, InvalidResponseDefinitionAsSchemaError, path, method) -// } -func someParametersBrokenMsg(path, method, operationID string) errors.Error { - return errors.New(errors.CompositeErrorCode, SomeParametersBrokenError, path, method, operationID) -} -func refShouldNotHaveSiblingsMsg(path, operationID string) errors.Error { - return errors.New(errors.CompositeErrorCode, RefShouldNotHaveSiblingsWarning, operationID, path) -} diff --git a/vendor/github.com/go-openapi/validate/type.go b/vendor/github.com/go-openapi/validate/type.go deleted file mode 100644 index f87abb3d5..000000000 --- a/vendor/github.com/go-openapi/validate/type.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "reflect" - "strings" - - "github.com/go-openapi/errors" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" -) - -type typeValidator struct { - Path string - In string - Type spec.StringOrArray - Nullable bool - Format string - Options *SchemaValidatorOptions -} - -func newTypeValidator(path, in string, typ spec.StringOrArray, nullable bool, format string, opts *SchemaValidatorOptions) *typeValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var t *typeValidator - if opts.recycleValidators { - t = pools.poolOfTypeValidators.BorrowValidator() - } else { - t = new(typeValidator) - } - - t.Path = path - t.In = in - t.Type = typ - t.Nullable = nullable - t.Format = format - t.Options = opts - - return t -} - -func (t *typeValidator) schemaInfoForType(data interface{}) (string, string) { - // internal type to JSON type with swagger 2.0 format (with go-openapi/strfmt extensions), - // see https://github.com/go-openapi/strfmt/blob/master/README.md - // TODO: this switch really is some sort of reverse lookup for formats. It should be provided by strfmt. - switch data.(type) { - case []byte, strfmt.Base64, *strfmt.Base64: - return stringType, stringFormatByte - case strfmt.CreditCard, *strfmt.CreditCard: - return stringType, stringFormatCreditCard - case strfmt.Date, *strfmt.Date: - return stringType, stringFormatDate - case strfmt.DateTime, *strfmt.DateTime: - return stringType, stringFormatDateTime - case strfmt.Duration, *strfmt.Duration: - return stringType, stringFormatDuration - case swag.File, *swag.File: - return fileType, "" - case strfmt.Email, *strfmt.Email: - return stringType, stringFormatEmail - case strfmt.HexColor, *strfmt.HexColor: - return stringType, stringFormatHexColor - case strfmt.Hostname, *strfmt.Hostname: - return stringType, stringFormatHostname - case strfmt.IPv4, *strfmt.IPv4: - return stringType, stringFormatIPv4 - case strfmt.IPv6, *strfmt.IPv6: - return stringType, stringFormatIPv6 - case strfmt.ISBN, *strfmt.ISBN: - return stringType, stringFormatISBN - case strfmt.ISBN10, *strfmt.ISBN10: - return stringType, stringFormatISBN10 - case strfmt.ISBN13, *strfmt.ISBN13: - return stringType, stringFormatISBN13 - case strfmt.MAC, *strfmt.MAC: - return stringType, stringFormatMAC - case strfmt.ObjectId, *strfmt.ObjectId: - return stringType, stringFormatBSONObjectID - case strfmt.Password, *strfmt.Password: - return stringType, stringFormatPassword - case strfmt.RGBColor, *strfmt.RGBColor: - return stringType, stringFormatRGBColor - case strfmt.SSN, *strfmt.SSN: - return stringType, stringFormatSSN - case strfmt.URI, *strfmt.URI: - return stringType, stringFormatURI - case strfmt.UUID, *strfmt.UUID: - return stringType, stringFormatUUID - case strfmt.UUID3, *strfmt.UUID3: - return stringType, stringFormatUUID3 - case strfmt.UUID4, *strfmt.UUID4: - return stringType, stringFormatUUID4 - case strfmt.UUID5, *strfmt.UUID5: - return stringType, stringFormatUUID5 - // TODO: missing binary (io.ReadCloser) - // TODO: missing json.Number - default: - val := reflect.ValueOf(data) - tpe := val.Type() - switch tpe.Kind() { //nolint:exhaustive - case reflect.Bool: - return booleanType, "" - case reflect.String: - return stringType, "" - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32: - // NOTE: that is the spec. With go-openapi, is that not uint32 for unsigned integers? - return integerType, integerFormatInt32 - case reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64: - return integerType, integerFormatInt64 - case reflect.Float32: - // NOTE: is that not numberFormatFloat? - return numberType, numberFormatFloat32 - case reflect.Float64: - // NOTE: is that not "double"? - return numberType, numberFormatFloat64 - // NOTE: go arrays (reflect.Array) are not supported (fixed length) - case reflect.Slice: - return arrayType, "" - case reflect.Map, reflect.Struct: - return objectType, "" - case reflect.Interface: - // What to do here? - panic("dunno what to do here") - case reflect.Ptr: - return t.schemaInfoForType(reflect.Indirect(val).Interface()) - } - } - return "", "" -} - -func (t *typeValidator) SetPath(path string) { - t.Path = path -} - -func (t *typeValidator) Applies(source interface{}, _ reflect.Kind) bool { - // typeValidator applies to Schema, Parameter and Header objects - switch source.(type) { - case *spec.Schema: - case *spec.Parameter: - case *spec.Header: - default: - return false - } - - return (len(t.Type) > 0 || t.Format != "") -} - -func (t *typeValidator) Validate(data interface{}) *Result { - if t.Options.recycleValidators { - defer func() { - t.redeem() - }() - } - - if data == nil { - // nil or zero value for the passed structure require Type: null - if len(t.Type) > 0 && !t.Type.Contains(nullType) && !t.Nullable { // TODO: if a property is not required it also passes this - return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), nullType), t.Options.recycleResult) - } - - return emptyResult - } - - // check if the type matches, should be used in every validator chain as first item - val := reflect.Indirect(reflect.ValueOf(data)) - kind := val.Kind() - - // infer schema type (JSON) and format from passed data type - schType, format := t.schemaInfoForType(data) - - // check numerical types - // TODO: check unsigned ints - // TODO: check json.Number (see schema.go) - isLowerInt := t.Format == integerFormatInt64 && format == integerFormatInt32 - isLowerFloat := t.Format == numberFormatFloat64 && format == numberFormatFloat32 - isFloatInt := schType == numberType && swag.IsFloat64AJSONInteger(val.Float()) && t.Type.Contains(integerType) - isIntFloat := schType == integerType && t.Type.Contains(numberType) - - if kind != reflect.String && kind != reflect.Slice && t.Format != "" && !(t.Type.Contains(schType) || format == t.Format || isFloatInt || isIntFloat || isLowerInt || isLowerFloat) { - // TODO: test case - return errorHelp.sErr(errors.InvalidType(t.Path, t.In, t.Format, format), t.Options.recycleResult) - } - - if !(t.Type.Contains(numberType) || t.Type.Contains(integerType)) && t.Format != "" && (kind == reflect.String || kind == reflect.Slice) { - return emptyResult - } - - if !(t.Type.Contains(schType) || isFloatInt || isIntFloat) { - return errorHelp.sErr(errors.InvalidType(t.Path, t.In, strings.Join(t.Type, ","), schType), t.Options.recycleResult) - } - - return emptyResult -} - -func (t *typeValidator) redeem() { - pools.poolOfTypeValidators.RedeemValidator(t) -} diff --git a/vendor/github.com/go-openapi/validate/update-fixtures.sh b/vendor/github.com/go-openapi/validate/update-fixtures.sh deleted file mode 100644 index 21b06e2b0..000000000 --- a/vendor/github.com/go-openapi/validate/update-fixtures.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -set -eu -o pipefail -dir=$(git rev-parse --show-toplevel) -scratch=$(mktemp -d -t tmp.XXXXXXXXXX) - -function finish { - rm -rf "$scratch" -} -trap finish EXIT SIGHUP SIGINT SIGTERM - -cd "$scratch" -git clone https://github.com/json-schema-org/JSON-Schema-Test-Suite Suite -cp -r Suite/tests/draft4/* "$dir/fixtures/jsonschema_suite" -cp -a Suite/remotes "$dir/fixtures/jsonschema_suite" diff --git a/vendor/github.com/go-openapi/validate/validator.go b/vendor/github.com/go-openapi/validate/validator.go deleted file mode 100644 index c083aecc9..000000000 --- a/vendor/github.com/go-openapi/validate/validator.go +++ /dev/null @@ -1,1051 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "fmt" - "reflect" - - "github.com/go-openapi/errors" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" -) - -// An EntityValidator is an interface for things that can validate entities -type EntityValidator interface { - Validate(interface{}) *Result -} - -type valueValidator interface { - SetPath(path string) - Applies(interface{}, reflect.Kind) bool - Validate(interface{}) *Result -} - -type itemsValidator struct { - items *spec.Items - root interface{} - path string - in string - validators [6]valueValidator - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions -} - -func newItemsValidator(path, in string, items *spec.Items, root interface{}, formats strfmt.Registry, opts *SchemaValidatorOptions) *itemsValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var iv *itemsValidator - if opts.recycleValidators { - iv = pools.poolOfItemsValidators.BorrowValidator() - } else { - iv = new(itemsValidator) - } - - iv.path = path - iv.in = in - iv.items = items - iv.root = root - iv.KnownFormats = formats - iv.Options = opts - iv.validators = [6]valueValidator{ - iv.typeValidator(), - iv.stringValidator(), - iv.formatValidator(), - iv.numberValidator(), - iv.sliceValidator(), - iv.commonValidator(), - } - return iv -} - -func (i *itemsValidator) Validate(index int, data interface{}) *Result { - if i.Options.recycleValidators { - defer func() { - i.redeemChildren() - i.redeem() - }() - } - - tpe := reflect.TypeOf(data) - kind := tpe.Kind() - var result *Result - if i.Options.recycleResult { - result = pools.poolOfResults.BorrowResult() - } else { - result = new(Result) - } - - path := fmt.Sprintf("%s.%d", i.path, index) - - for idx, validator := range i.validators { - if !validator.Applies(i.root, kind) { - if i.Options.recycleValidators { - // Validate won't be called, so relinquish this validator - if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok { - redeemableChildren.redeemChildren() - } - if redeemable, ok := validator.(interface{ redeem() }); ok { - redeemable.redeem() - } - i.validators[idx] = nil // prevents further (unsafe) usage - } - - continue - } - - validator.SetPath(path) - err := validator.Validate(data) - if i.Options.recycleValidators { - i.validators[idx] = nil // prevents further (unsafe) usage - } - if err != nil { - result.Inc() - if err.HasErrors() { - result.Merge(err) - - break - } - - result.Merge(err) - } - } - - return result -} - -func (i *itemsValidator) typeValidator() valueValidator { - return newTypeValidator( - i.path, - i.in, - spec.StringOrArray([]string{i.items.Type}), - i.items.Nullable, - i.items.Format, - i.Options, - ) -} - -func (i *itemsValidator) commonValidator() valueValidator { - return newBasicCommonValidator( - "", - i.in, - i.items.Default, - i.items.Enum, - i.Options, - ) -} - -func (i *itemsValidator) sliceValidator() valueValidator { - return newBasicSliceValidator( - "", - i.in, - i.items.Default, - i.items.MaxItems, - i.items.MinItems, - i.items.UniqueItems, - i.items.Items, - i.root, - i.KnownFormats, - i.Options, - ) -} - -func (i *itemsValidator) numberValidator() valueValidator { - return newNumberValidator( - "", - i.in, - i.items.Default, - i.items.MultipleOf, - i.items.Maximum, - i.items.ExclusiveMaximum, - i.items.Minimum, - i.items.ExclusiveMinimum, - i.items.Type, - i.items.Format, - i.Options, - ) -} - -func (i *itemsValidator) stringValidator() valueValidator { - return newStringValidator( - "", - i.in, - i.items.Default, - false, // Required - false, // AllowEmpty - i.items.MaxLength, - i.items.MinLength, - i.items.Pattern, - i.Options, - ) -} - -func (i *itemsValidator) formatValidator() valueValidator { - return newFormatValidator( - "", - i.in, - i.items.Format, - i.KnownFormats, - i.Options, - ) -} - -func (i *itemsValidator) redeem() { - pools.poolOfItemsValidators.RedeemValidator(i) -} - -func (i *itemsValidator) redeemChildren() { - for idx, validator := range i.validators { - if validator == nil { - continue - } - if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok { - redeemableChildren.redeemChildren() - } - if redeemable, ok := validator.(interface{ redeem() }); ok { - redeemable.redeem() - } - i.validators[idx] = nil // free up allocated children if not in pool - } -} - -type basicCommonValidator struct { - Path string - In string - Default interface{} - Enum []interface{} - Options *SchemaValidatorOptions -} - -func newBasicCommonValidator(path, in string, def interface{}, enum []interface{}, opts *SchemaValidatorOptions) *basicCommonValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var b *basicCommonValidator - if opts.recycleValidators { - b = pools.poolOfBasicCommonValidators.BorrowValidator() - } else { - b = new(basicCommonValidator) - } - - b.Path = path - b.In = in - b.Default = def - b.Enum = enum - b.Options = opts - - return b -} - -func (b *basicCommonValidator) SetPath(path string) { - b.Path = path -} - -func (b *basicCommonValidator) Applies(source interface{}, _ reflect.Kind) bool { - switch source.(type) { - case *spec.Parameter, *spec.Schema, *spec.Header: - return true - default: - return false - } -} - -func (b *basicCommonValidator) Validate(data interface{}) (res *Result) { - if b.Options.recycleValidators { - defer func() { - b.redeem() - }() - } - - if len(b.Enum) == 0 { - return nil - } - - for _, enumValue := range b.Enum { - actualType := reflect.TypeOf(enumValue) - if actualType == nil { // Safeguard - continue - } - - expectedValue := reflect.ValueOf(data) - if expectedValue.IsValid() && - expectedValue.Type().ConvertibleTo(actualType) && - reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), enumValue) { - return nil - } - } - - return errorHelp.sErr(errors.EnumFail(b.Path, b.In, data, b.Enum), b.Options.recycleResult) -} - -func (b *basicCommonValidator) redeem() { - pools.poolOfBasicCommonValidators.RedeemValidator(b) -} - -// A HeaderValidator has very limited subset of validations to apply -type HeaderValidator struct { - name string - header *spec.Header - validators [6]valueValidator - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions -} - -// NewHeaderValidator creates a new header validator object -func NewHeaderValidator(name string, header *spec.Header, formats strfmt.Registry, options ...Option) *HeaderValidator { - opts := new(SchemaValidatorOptions) - for _, o := range options { - o(opts) - } - - return newHeaderValidator(name, header, formats, opts) -} - -func newHeaderValidator(name string, header *spec.Header, formats strfmt.Registry, opts *SchemaValidatorOptions) *HeaderValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var p *HeaderValidator - if opts.recycleValidators { - p = pools.poolOfHeaderValidators.BorrowValidator() - } else { - p = new(HeaderValidator) - } - - p.name = name - p.header = header - p.KnownFormats = formats - p.Options = opts - p.validators = [6]valueValidator{ - newTypeValidator( - name, - "header", - spec.StringOrArray([]string{header.Type}), - header.Nullable, - header.Format, - p.Options, - ), - p.stringValidator(), - p.formatValidator(), - p.numberValidator(), - p.sliceValidator(), - p.commonValidator(), - } - - return p -} - -// Validate the value of the header against its schema -func (p *HeaderValidator) Validate(data interface{}) *Result { - if p.Options.recycleValidators { - defer func() { - p.redeemChildren() - p.redeem() - }() - } - - if data == nil { - return nil - } - - var result *Result - if p.Options.recycleResult { - result = pools.poolOfResults.BorrowResult() - } else { - result = new(Result) - } - - tpe := reflect.TypeOf(data) - kind := tpe.Kind() - - for idx, validator := range p.validators { - if !validator.Applies(p.header, kind) { - if p.Options.recycleValidators { - // Validate won't be called, so relinquish this validator - if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok { - redeemableChildren.redeemChildren() - } - if redeemable, ok := validator.(interface{ redeem() }); ok { - redeemable.redeem() - } - p.validators[idx] = nil // prevents further (unsafe) usage - } - - continue - } - - err := validator.Validate(data) - if p.Options.recycleValidators { - p.validators[idx] = nil // prevents further (unsafe) usage - } - if err != nil { - if err.HasErrors() { - result.Merge(err) - break - } - result.Merge(err) - } - } - - return result -} - -func (p *HeaderValidator) commonValidator() valueValidator { - return newBasicCommonValidator( - p.name, - "response", - p.header.Default, - p.header.Enum, - p.Options, - ) -} - -func (p *HeaderValidator) sliceValidator() valueValidator { - return newBasicSliceValidator( - p.name, - "response", - p.header.Default, - p.header.MaxItems, - p.header.MinItems, - p.header.UniqueItems, - p.header.Items, - p.header, - p.KnownFormats, - p.Options, - ) -} - -func (p *HeaderValidator) numberValidator() valueValidator { - return newNumberValidator( - p.name, - "response", - p.header.Default, - p.header.MultipleOf, - p.header.Maximum, - p.header.ExclusiveMaximum, - p.header.Minimum, - p.header.ExclusiveMinimum, - p.header.Type, - p.header.Format, - p.Options, - ) -} - -func (p *HeaderValidator) stringValidator() valueValidator { - return newStringValidator( - p.name, - "response", - p.header.Default, - true, - false, - p.header.MaxLength, - p.header.MinLength, - p.header.Pattern, - p.Options, - ) -} - -func (p *HeaderValidator) formatValidator() valueValidator { - return newFormatValidator( - p.name, - "response", - p.header.Format, - p.KnownFormats, - p.Options, - ) -} - -func (p *HeaderValidator) redeem() { - pools.poolOfHeaderValidators.RedeemValidator(p) -} - -func (p *HeaderValidator) redeemChildren() { - for idx, validator := range p.validators { - if validator == nil { - continue - } - if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok { - redeemableChildren.redeemChildren() - } - if redeemable, ok := validator.(interface{ redeem() }); ok { - redeemable.redeem() - } - p.validators[idx] = nil // free up allocated children if not in pool - } -} - -// A ParamValidator has very limited subset of validations to apply -type ParamValidator struct { - param *spec.Parameter - validators [6]valueValidator - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions -} - -// NewParamValidator creates a new param validator object -func NewParamValidator(param *spec.Parameter, formats strfmt.Registry, options ...Option) *ParamValidator { - opts := new(SchemaValidatorOptions) - for _, o := range options { - o(opts) - } - - return newParamValidator(param, formats, opts) -} - -func newParamValidator(param *spec.Parameter, formats strfmt.Registry, opts *SchemaValidatorOptions) *ParamValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var p *ParamValidator - if opts.recycleValidators { - p = pools.poolOfParamValidators.BorrowValidator() - } else { - p = new(ParamValidator) - } - - p.param = param - p.KnownFormats = formats - p.Options = opts - p.validators = [6]valueValidator{ - newTypeValidator( - param.Name, - param.In, - spec.StringOrArray([]string{param.Type}), - param.Nullable, - param.Format, - p.Options, - ), - p.stringValidator(), - p.formatValidator(), - p.numberValidator(), - p.sliceValidator(), - p.commonValidator(), - } - - return p -} - -// Validate the data against the description of the parameter -func (p *ParamValidator) Validate(data interface{}) *Result { - if data == nil { - return nil - } - - var result *Result - if p.Options.recycleResult { - result = pools.poolOfResults.BorrowResult() - } else { - result = new(Result) - } - - tpe := reflect.TypeOf(data) - kind := tpe.Kind() - - if p.Options.recycleValidators { - defer func() { - p.redeemChildren() - p.redeem() - }() - } - - // TODO: validate type - for idx, validator := range p.validators { - if !validator.Applies(p.param, kind) { - if p.Options.recycleValidators { - // Validate won't be called, so relinquish this validator - if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok { - redeemableChildren.redeemChildren() - } - if redeemable, ok := validator.(interface{ redeem() }); ok { - redeemable.redeem() - } - p.validators[idx] = nil // prevents further (unsafe) usage - } - - continue - } - - err := validator.Validate(data) - if p.Options.recycleValidators { - p.validators[idx] = nil // prevents further (unsafe) usage - } - if err != nil { - if err.HasErrors() { - result.Merge(err) - break - } - result.Merge(err) - } - } - - return result -} - -func (p *ParamValidator) commonValidator() valueValidator { - return newBasicCommonValidator( - p.param.Name, - p.param.In, - p.param.Default, - p.param.Enum, - p.Options, - ) -} - -func (p *ParamValidator) sliceValidator() valueValidator { - return newBasicSliceValidator( - p.param.Name, - p.param.In, - p.param.Default, - p.param.MaxItems, - p.param.MinItems, - p.param.UniqueItems, - p.param.Items, - p.param, - p.KnownFormats, - p.Options, - ) -} - -func (p *ParamValidator) numberValidator() valueValidator { - return newNumberValidator( - p.param.Name, - p.param.In, - p.param.Default, - p.param.MultipleOf, - p.param.Maximum, - p.param.ExclusiveMaximum, - p.param.Minimum, - p.param.ExclusiveMinimum, - p.param.Type, - p.param.Format, - p.Options, - ) -} - -func (p *ParamValidator) stringValidator() valueValidator { - return newStringValidator( - p.param.Name, - p.param.In, - p.param.Default, - p.param.Required, - p.param.AllowEmptyValue, - p.param.MaxLength, - p.param.MinLength, - p.param.Pattern, - p.Options, - ) -} - -func (p *ParamValidator) formatValidator() valueValidator { - return newFormatValidator( - p.param.Name, - p.param.In, - p.param.Format, - p.KnownFormats, - p.Options, - ) -} - -func (p *ParamValidator) redeem() { - pools.poolOfParamValidators.RedeemValidator(p) -} - -func (p *ParamValidator) redeemChildren() { - for idx, validator := range p.validators { - if validator == nil { - continue - } - if redeemableChildren, ok := validator.(interface{ redeemChildren() }); ok { - redeemableChildren.redeemChildren() - } - if redeemable, ok := validator.(interface{ redeem() }); ok { - redeemable.redeem() - } - p.validators[idx] = nil // free up allocated children if not in pool - } -} - -type basicSliceValidator struct { - Path string - In string - Default interface{} - MaxItems *int64 - MinItems *int64 - UniqueItems bool - Items *spec.Items - Source interface{} - KnownFormats strfmt.Registry - Options *SchemaValidatorOptions -} - -func newBasicSliceValidator( - path, in string, - def interface{}, maxItems, minItems *int64, uniqueItems bool, items *spec.Items, - source interface{}, formats strfmt.Registry, - opts *SchemaValidatorOptions) *basicSliceValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var s *basicSliceValidator - if opts.recycleValidators { - s = pools.poolOfBasicSliceValidators.BorrowValidator() - } else { - s = new(basicSliceValidator) - } - - s.Path = path - s.In = in - s.Default = def - s.MaxItems = maxItems - s.MinItems = minItems - s.UniqueItems = uniqueItems - s.Items = items - s.Source = source - s.KnownFormats = formats - s.Options = opts - - return s -} - -func (s *basicSliceValidator) SetPath(path string) { - s.Path = path -} - -func (s *basicSliceValidator) Applies(source interface{}, kind reflect.Kind) bool { - switch source.(type) { - case *spec.Parameter, *spec.Items, *spec.Header: - return kind == reflect.Slice - default: - return false - } -} - -func (s *basicSliceValidator) Validate(data interface{}) *Result { - if s.Options.recycleValidators { - defer func() { - s.redeem() - }() - } - val := reflect.ValueOf(data) - - size := int64(val.Len()) - if s.MinItems != nil { - if err := MinItems(s.Path, s.In, size, *s.MinItems); err != nil { - return errorHelp.sErr(err, s.Options.recycleResult) - } - } - - if s.MaxItems != nil { - if err := MaxItems(s.Path, s.In, size, *s.MaxItems); err != nil { - return errorHelp.sErr(err, s.Options.recycleResult) - } - } - - if s.UniqueItems { - if err := UniqueItems(s.Path, s.In, data); err != nil { - return errorHelp.sErr(err, s.Options.recycleResult) - } - } - - if s.Items == nil { - return nil - } - - for i := 0; i < int(size); i++ { - itemsValidator := newItemsValidator(s.Path, s.In, s.Items, s.Source, s.KnownFormats, s.Options) - ele := val.Index(i) - if err := itemsValidator.Validate(i, ele.Interface()); err != nil { - if err.HasErrors() { - return err - } - if err.wantsRedeemOnMerge { - pools.poolOfResults.RedeemResult(err) - } - } - } - - return nil -} - -func (s *basicSliceValidator) redeem() { - pools.poolOfBasicSliceValidators.RedeemValidator(s) -} - -type numberValidator struct { - Path string - In string - Default interface{} - MultipleOf *float64 - Maximum *float64 - ExclusiveMaximum bool - Minimum *float64 - ExclusiveMinimum bool - // Allows for more accurate behavior regarding integers - Type string - Format string - Options *SchemaValidatorOptions -} - -func newNumberValidator( - path, in string, def interface{}, - multipleOf, maximum *float64, exclusiveMaximum bool, minimum *float64, exclusiveMinimum bool, - typ, format string, - opts *SchemaValidatorOptions) *numberValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var n *numberValidator - if opts.recycleValidators { - n = pools.poolOfNumberValidators.BorrowValidator() - } else { - n = new(numberValidator) - } - - n.Path = path - n.In = in - n.Default = def - n.MultipleOf = multipleOf - n.Maximum = maximum - n.ExclusiveMaximum = exclusiveMaximum - n.Minimum = minimum - n.ExclusiveMinimum = exclusiveMinimum - n.Type = typ - n.Format = format - n.Options = opts - - return n -} - -func (n *numberValidator) SetPath(path string) { - n.Path = path -} - -func (n *numberValidator) Applies(source interface{}, kind reflect.Kind) bool { - switch source.(type) { - case *spec.Parameter, *spec.Schema, *spec.Items, *spec.Header: - isInt := kind >= reflect.Int && kind <= reflect.Uint64 - isFloat := kind == reflect.Float32 || kind == reflect.Float64 - return isInt || isFloat - default: - return false - } -} - -// Validate provides a validator for generic JSON numbers, -// -// By default, numbers are internally represented as float64. -// Formats float, or float32 may alter this behavior by mapping to float32. -// A special validation process is followed for integers, with optional "format": -// this is an attempt to provide a validation with native types. -// -// NOTE: since the constraint specified (boundary, multipleOf) is unmarshalled -// as float64, loss of information remains possible (e.g. on very large integers). -// -// Since this value directly comes from the unmarshalling, it is not possible -// at this stage of processing to check further and guarantee the correctness of such values. -// -// Normally, the JSON Number.MAX_SAFE_INTEGER (resp. Number.MIN_SAFE_INTEGER) -// would check we do not get such a loss. -// -// If this is the case, replace AddErrors() by AddWarnings() and IsValid() by !HasWarnings(). -// -// TODO: consider replacing boundary check errors by simple warnings. -// -// TODO: default boundaries with MAX_SAFE_INTEGER are not checked (specific to json.Number?) -func (n *numberValidator) Validate(val interface{}) *Result { - if n.Options.recycleValidators { - defer func() { - n.redeem() - }() - } - - var res, resMultiple, resMinimum, resMaximum *Result - if n.Options.recycleResult { - res = pools.poolOfResults.BorrowResult() - } else { - res = new(Result) - } - - // Used only to attempt to validate constraint on value, - // even though value or constraint specified do not match type and format - data := valueHelp.asFloat64(val) - - // Is the provided value within the range of the specified numeric type and format? - res.AddErrors(IsValueValidAgainstRange(val, n.Type, n.Format, "Checked", n.Path)) - - if n.MultipleOf != nil { - resMultiple = pools.poolOfResults.BorrowResult() - - // Is the constraint specifier within the range of the specific numeric type and format? - resMultiple.AddErrors(IsValueValidAgainstRange(*n.MultipleOf, n.Type, n.Format, "MultipleOf", n.Path)) - if resMultiple.IsValid() { - // Constraint validated with compatible types - if err := MultipleOfNativeType(n.Path, n.In, val, *n.MultipleOf); err != nil { - resMultiple.Merge(errorHelp.sErr(err, n.Options.recycleResult)) - } - } else { - // Constraint nevertheless validated, converted as general number - if err := MultipleOf(n.Path, n.In, data, *n.MultipleOf); err != nil { - resMultiple.Merge(errorHelp.sErr(err, n.Options.recycleResult)) - } - } - } - - if n.Maximum != nil { - resMaximum = pools.poolOfResults.BorrowResult() - - // Is the constraint specifier within the range of the specific numeric type and format? - resMaximum.AddErrors(IsValueValidAgainstRange(*n.Maximum, n.Type, n.Format, "Maximum boundary", n.Path)) - if resMaximum.IsValid() { - // Constraint validated with compatible types - if err := MaximumNativeType(n.Path, n.In, val, *n.Maximum, n.ExclusiveMaximum); err != nil { - resMaximum.Merge(errorHelp.sErr(err, n.Options.recycleResult)) - } - } else { - // Constraint nevertheless validated, converted as general number - if err := Maximum(n.Path, n.In, data, *n.Maximum, n.ExclusiveMaximum); err != nil { - resMaximum.Merge(errorHelp.sErr(err, n.Options.recycleResult)) - } - } - } - - if n.Minimum != nil { - resMinimum = pools.poolOfResults.BorrowResult() - - // Is the constraint specifier within the range of the specific numeric type and format? - resMinimum.AddErrors(IsValueValidAgainstRange(*n.Minimum, n.Type, n.Format, "Minimum boundary", n.Path)) - if resMinimum.IsValid() { - // Constraint validated with compatible types - if err := MinimumNativeType(n.Path, n.In, val, *n.Minimum, n.ExclusiveMinimum); err != nil { - resMinimum.Merge(errorHelp.sErr(err, n.Options.recycleResult)) - } - } else { - // Constraint nevertheless validated, converted as general number - if err := Minimum(n.Path, n.In, data, *n.Minimum, n.ExclusiveMinimum); err != nil { - resMinimum.Merge(errorHelp.sErr(err, n.Options.recycleResult)) - } - } - } - res.Merge(resMultiple, resMinimum, resMaximum) - res.Inc() - - return res -} - -func (n *numberValidator) redeem() { - pools.poolOfNumberValidators.RedeemValidator(n) -} - -type stringValidator struct { - Path string - In string - Default interface{} - Required bool - AllowEmptyValue bool - MaxLength *int64 - MinLength *int64 - Pattern string - Options *SchemaValidatorOptions -} - -func newStringValidator( - path, in string, - def interface{}, required, allowEmpty bool, maxLength, minLength *int64, pattern string, - opts *SchemaValidatorOptions) *stringValidator { - if opts == nil { - opts = new(SchemaValidatorOptions) - } - - var s *stringValidator - if opts.recycleValidators { - s = pools.poolOfStringValidators.BorrowValidator() - } else { - s = new(stringValidator) - } - - s.Path = path - s.In = in - s.Default = def - s.Required = required - s.AllowEmptyValue = allowEmpty - s.MaxLength = maxLength - s.MinLength = minLength - s.Pattern = pattern - s.Options = opts - - return s -} - -func (s *stringValidator) SetPath(path string) { - s.Path = path -} - -func (s *stringValidator) Applies(source interface{}, kind reflect.Kind) bool { - switch source.(type) { - case *spec.Parameter, *spec.Schema, *spec.Items, *spec.Header: - return kind == reflect.String - default: - return false - } -} - -func (s *stringValidator) Validate(val interface{}) *Result { - if s.Options.recycleValidators { - defer func() { - s.redeem() - }() - } - - data, ok := val.(string) - if !ok { - return errorHelp.sErr(errors.InvalidType(s.Path, s.In, stringType, val), s.Options.recycleResult) - } - - if s.Required && !s.AllowEmptyValue && (s.Default == nil || s.Default == "") { - if err := RequiredString(s.Path, s.In, data); err != nil { - return errorHelp.sErr(err, s.Options.recycleResult) - } - } - - if s.MaxLength != nil { - if err := MaxLength(s.Path, s.In, data, *s.MaxLength); err != nil { - return errorHelp.sErr(err, s.Options.recycleResult) - } - } - - if s.MinLength != nil { - if err := MinLength(s.Path, s.In, data, *s.MinLength); err != nil { - return errorHelp.sErr(err, s.Options.recycleResult) - } - } - - if s.Pattern != "" { - if err := Pattern(s.Path, s.In, data, s.Pattern); err != nil { - return errorHelp.sErr(err, s.Options.recycleResult) - } - } - return nil -} - -func (s *stringValidator) redeem() { - pools.poolOfStringValidators.RedeemValidator(s) -} diff --git a/vendor/github.com/go-openapi/validate/values.go b/vendor/github.com/go-openapi/validate/values.go deleted file mode 100644 index 5f6f5ee61..000000000 --- a/vendor/github.com/go-openapi/validate/values.go +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validate - -import ( - "context" - "fmt" - "reflect" - "strings" - "unicode/utf8" - - "github.com/go-openapi/errors" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" -) - -// Enum validates if the data is a member of the enum -func Enum(path, in string, data interface{}, enum interface{}) *errors.Validation { - return EnumCase(path, in, data, enum, true) -} - -// EnumCase validates if the data is a member of the enum and may respect case-sensitivity for strings -func EnumCase(path, in string, data interface{}, enum interface{}, caseSensitive bool) *errors.Validation { - val := reflect.ValueOf(enum) - if val.Kind() != reflect.Slice { - return nil - } - - dataString := convertEnumCaseStringKind(data, caseSensitive) - var values []interface{} - for i := 0; i < val.Len(); i++ { - ele := val.Index(i) - enumValue := ele.Interface() - if data != nil { - if reflect.DeepEqual(data, enumValue) { - return nil - } - enumString := convertEnumCaseStringKind(enumValue, caseSensitive) - if dataString != nil && enumString != nil && strings.EqualFold(*dataString, *enumString) { - return nil - } - actualType := reflect.TypeOf(enumValue) - if actualType == nil { // Safeguard. Frankly, I don't know how we may get a nil - continue - } - expectedValue := reflect.ValueOf(data) - if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { - // Attempt comparison after type conversion - if reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), enumValue) { - return nil - } - } - } - values = append(values, enumValue) - } - return errors.EnumFail(path, in, data, values) -} - -// convertEnumCaseStringKind converts interface if it is kind of string and case insensitivity is set -func convertEnumCaseStringKind(value interface{}, caseSensitive bool) *string { - if caseSensitive { - return nil - } - - val := reflect.ValueOf(value) - if val.Kind() != reflect.String { - return nil - } - - str := fmt.Sprintf("%v", value) - return &str -} - -// MinItems validates that there are at least n items in a slice -func MinItems(path, in string, size, min int64) *errors.Validation { - if size < min { - return errors.TooFewItems(path, in, min, size) - } - return nil -} - -// MaxItems validates that there are at most n items in a slice -func MaxItems(path, in string, size, max int64) *errors.Validation { - if size > max { - return errors.TooManyItems(path, in, max, size) - } - return nil -} - -// UniqueItems validates that the provided slice has unique elements -func UniqueItems(path, in string, data interface{}) *errors.Validation { - val := reflect.ValueOf(data) - if val.Kind() != reflect.Slice { - return nil - } - var unique []interface{} - for i := 0; i < val.Len(); i++ { - v := val.Index(i).Interface() - for _, u := range unique { - if reflect.DeepEqual(v, u) { - return errors.DuplicateItems(path, in) - } - } - unique = append(unique, v) - } - return nil -} - -// MinLength validates a string for minimum length -func MinLength(path, in, data string, minLength int64) *errors.Validation { - strLen := int64(utf8.RuneCountInString(data)) - if strLen < minLength { - return errors.TooShort(path, in, minLength, data) - } - return nil -} - -// MaxLength validates a string for maximum length -func MaxLength(path, in, data string, maxLength int64) *errors.Validation { - strLen := int64(utf8.RuneCountInString(data)) - if strLen > maxLength { - return errors.TooLong(path, in, maxLength, data) - } - return nil -} - -// ReadOnly validates an interface for readonly -func ReadOnly(ctx context.Context, path, in string, data interface{}) *errors.Validation { - - // read only is only validated when operationType is request - if op := extractOperationType(ctx); op != request { - return nil - } - - // data must be of zero value of its type - val := reflect.ValueOf(data) - if val.IsValid() { - if reflect.DeepEqual(reflect.Zero(val.Type()).Interface(), val.Interface()) { - return nil - } - } else { - return nil - } - - return errors.ReadOnly(path, in, data) -} - -// Required validates an interface for requiredness -func Required(path, in string, data interface{}) *errors.Validation { - val := reflect.ValueOf(data) - if val.IsValid() { - if reflect.DeepEqual(reflect.Zero(val.Type()).Interface(), val.Interface()) { - return errors.Required(path, in, data) - } - return nil - } - return errors.Required(path, in, data) -} - -// RequiredString validates a string for requiredness -func RequiredString(path, in, data string) *errors.Validation { - if data == "" { - return errors.Required(path, in, data) - } - return nil -} - -// RequiredNumber validates a number for requiredness -func RequiredNumber(path, in string, data float64) *errors.Validation { - if data == 0 { - return errors.Required(path, in, data) - } - return nil -} - -// Pattern validates a string against a regular expression -func Pattern(path, in, data, pattern string) *errors.Validation { - re, err := compileRegexp(pattern) - if err != nil { - return errors.FailedPattern(path, in, fmt.Sprintf("%s, but pattern is invalid: %s", pattern, err.Error()), data) - } - if !re.MatchString(data) { - return errors.FailedPattern(path, in, pattern, data) - } - return nil -} - -// MaximumInt validates if a number is smaller than a given maximum -func MaximumInt(path, in string, data, max int64, exclusive bool) *errors.Validation { - if (!exclusive && data > max) || (exclusive && data >= max) { - return errors.ExceedsMaximumInt(path, in, max, exclusive, data) - } - return nil -} - -// MaximumUint validates if a number is smaller than a given maximum -func MaximumUint(path, in string, data, max uint64, exclusive bool) *errors.Validation { - if (!exclusive && data > max) || (exclusive && data >= max) { - return errors.ExceedsMaximumUint(path, in, max, exclusive, data) - } - return nil -} - -// Maximum validates if a number is smaller than a given maximum -func Maximum(path, in string, data, max float64, exclusive bool) *errors.Validation { - if (!exclusive && data > max) || (exclusive && data >= max) { - return errors.ExceedsMaximum(path, in, max, exclusive, data) - } - return nil -} - -// Minimum validates if a number is smaller than a given minimum -func Minimum(path, in string, data, min float64, exclusive bool) *errors.Validation { - if (!exclusive && data < min) || (exclusive && data <= min) { - return errors.ExceedsMinimum(path, in, min, exclusive, data) - } - return nil -} - -// MinimumInt validates if a number is smaller than a given minimum -func MinimumInt(path, in string, data, min int64, exclusive bool) *errors.Validation { - if (!exclusive && data < min) || (exclusive && data <= min) { - return errors.ExceedsMinimumInt(path, in, min, exclusive, data) - } - return nil -} - -// MinimumUint validates if a number is smaller than a given minimum -func MinimumUint(path, in string, data, min uint64, exclusive bool) *errors.Validation { - if (!exclusive && data < min) || (exclusive && data <= min) { - return errors.ExceedsMinimumUint(path, in, min, exclusive, data) - } - return nil -} - -// MultipleOf validates if the provided number is a multiple of the factor -func MultipleOf(path, in string, data, factor float64) *errors.Validation { - // multipleOf factor must be positive - if factor <= 0 { - return errors.MultipleOfMustBePositive(path, in, factor) - } - var mult float64 - if factor < 1 { - mult = 1 / factor * data - } else { - mult = data / factor - } - if !swag.IsFloat64AJSONInteger(mult) { - return errors.NotMultipleOf(path, in, factor, data) - } - return nil -} - -// MultipleOfInt validates if the provided integer is a multiple of the factor -func MultipleOfInt(path, in string, data int64, factor int64) *errors.Validation { - // multipleOf factor must be positive - if factor <= 0 { - return errors.MultipleOfMustBePositive(path, in, factor) - } - mult := data / factor - if mult*factor != data { - return errors.NotMultipleOf(path, in, factor, data) - } - return nil -} - -// MultipleOfUint validates if the provided unsigned integer is a multiple of the factor -func MultipleOfUint(path, in string, data, factor uint64) *errors.Validation { - // multipleOf factor must be positive - if factor == 0 { - return errors.MultipleOfMustBePositive(path, in, factor) - } - mult := data / factor - if mult*factor != data { - return errors.NotMultipleOf(path, in, factor, data) - } - return nil -} - -// FormatOf validates if a string matches a format in the format registry -func FormatOf(path, in, format, data string, registry strfmt.Registry) *errors.Validation { - if registry == nil { - registry = strfmt.Default - } - if ok := registry.ContainsName(format); !ok { - return errors.InvalidTypeName(format) - } - if ok := registry.Validates(format, data); !ok { - return errors.InvalidType(path, in, format, data) - } - return nil -} - -// MaximumNativeType provides native type constraint validation as a facade -// to various numeric types versions of Maximum constraint check. -// -// Assumes that any possible loss conversion during conversion has been -// checked beforehand. -// -// NOTE: currently, the max value is marshalled as a float64, no matter what, -// which means there may be a loss during conversions (e.g. for very large integers) -// -// TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free -func MaximumNativeType(path, in string, val interface{}, max float64, exclusive bool) *errors.Validation { - kind := reflect.ValueOf(val).Type().Kind() - switch kind { //nolint:exhaustive - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - value := valueHelp.asInt64(val) - return MaximumInt(path, in, value, int64(max), exclusive) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - value := valueHelp.asUint64(val) - if max < 0 { - return errors.ExceedsMaximum(path, in, max, exclusive, val) - } - return MaximumUint(path, in, value, uint64(max), exclusive) - case reflect.Float32, reflect.Float64: - fallthrough - default: - value := valueHelp.asFloat64(val) - return Maximum(path, in, value, max, exclusive) - } -} - -// MinimumNativeType provides native type constraint validation as a facade -// to various numeric types versions of Minimum constraint check. -// -// Assumes that any possible loss conversion during conversion has been -// checked beforehand. -// -// NOTE: currently, the min value is marshalled as a float64, no matter what, -// which means there may be a loss during conversions (e.g. for very large integers) -// -// TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free -func MinimumNativeType(path, in string, val interface{}, min float64, exclusive bool) *errors.Validation { - kind := reflect.ValueOf(val).Type().Kind() - switch kind { //nolint:exhaustive - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - value := valueHelp.asInt64(val) - return MinimumInt(path, in, value, int64(min), exclusive) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - value := valueHelp.asUint64(val) - if min < 0 { - return nil - } - return MinimumUint(path, in, value, uint64(min), exclusive) - case reflect.Float32, reflect.Float64: - fallthrough - default: - value := valueHelp.asFloat64(val) - return Minimum(path, in, value, min, exclusive) - } -} - -// MultipleOfNativeType provides native type constraint validation as a facade -// to various numeric types version of MultipleOf constraint check. -// -// Assumes that any possible loss conversion during conversion has been -// checked beforehand. -// -// NOTE: currently, the multipleOf factor is marshalled as a float64, no matter what, -// which means there may be a loss during conversions (e.g. for very large integers) -// -// TODO: Normally, a JSON MAX_SAFE_INTEGER check would ensure conversion remains loss-free -func MultipleOfNativeType(path, in string, val interface{}, multipleOf float64) *errors.Validation { - kind := reflect.ValueOf(val).Type().Kind() - switch kind { //nolint:exhaustive - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - value := valueHelp.asInt64(val) - return MultipleOfInt(path, in, value, int64(multipleOf)) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - value := valueHelp.asUint64(val) - return MultipleOfUint(path, in, value, uint64(multipleOf)) - case reflect.Float32, reflect.Float64: - fallthrough - default: - value := valueHelp.asFloat64(val) - return MultipleOf(path, in, value, multipleOf) - } -} - -// IsValueValidAgainstRange checks that a numeric value is compatible with -// the range defined by Type and Format, that is, may be converted without loss. -// -// NOTE: this check is about type capacity and not formal verification such as: 1.0 != 1L -func IsValueValidAgainstRange(val interface{}, typeName, format, prefix, path string) error { - kind := reflect.ValueOf(val).Type().Kind() - - // What is the string representation of val - var stringRep string - switch kind { //nolint:exhaustive - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - stringRep = swag.FormatUint64(valueHelp.asUint64(val)) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - stringRep = swag.FormatInt64(valueHelp.asInt64(val)) - case reflect.Float32, reflect.Float64: - stringRep = swag.FormatFloat64(valueHelp.asFloat64(val)) - default: - return fmt.Errorf("%s value number range checking called with invalid (non numeric) val type in %s", prefix, path) - } - - var errVal error - - switch typeName { - case integerType: - switch format { - case integerFormatInt32: - _, errVal = swag.ConvertInt32(stringRep) - case integerFormatUInt32: - _, errVal = swag.ConvertUint32(stringRep) - case integerFormatUInt64: - _, errVal = swag.ConvertUint64(stringRep) - case integerFormatInt64: - fallthrough - default: - _, errVal = swag.ConvertInt64(stringRep) - } - case numberType: - fallthrough - default: - switch format { - case numberFormatFloat, numberFormatFloat32: - _, errVal = swag.ConvertFloat32(stringRep) - case numberFormatDouble, numberFormatFloat64: - fallthrough - default: - // No check can be performed here since - // no number beyond float64 is supported - } - } - if errVal != nil { // We don't report the actual errVal from strconv - if format != "" { - errVal = fmt.Errorf("%s value must be of type %s with format %s in %s", prefix, typeName, format, path) - } else { - errVal = fmt.Errorf("%s value must be of type %s (default format) in %s", prefix, typeName, path) - } - } - return errVal -} |