Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions datamodel/low/base/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package base
import (
"context"
"crypto/sha256"
"strings"

"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
Expand Down Expand Up @@ -64,17 +63,25 @@ func (c *Contact) GetKeyNode() *yaml.Node {

// Hash will return a consistent SHA256 Hash of the Contact object
func (c *Contact) Hash() [32]byte {
var f []string
// Use string builder pool
sb := low.GetStringBuilder()
defer low.PutStringBuilder(sb)

if !c.Name.IsEmpty() {
f = append(f, c.Name.Value)
sb.WriteString(c.Name.Value)
sb.WriteByte('|')
}
if !c.URL.IsEmpty() {
f = append(f, c.URL.Value)
sb.WriteString(c.URL.Value)
sb.WriteByte('|')
}
if !c.Email.IsEmpty() {
f = append(f, c.Email.Value)
sb.WriteString(c.Email.Value)
sb.WriteByte('|')
}
return sha256.Sum256([]byte(strings.Join(f, "|")))

// Note: Extensions are not included in the hash for Contact
return sha256.Sum256([]byte(sb.String()))
}

// GetExtensions returns all extensions for Contact
Expand Down
15 changes: 9 additions & 6 deletions datamodel/low/base/discriminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package base

import (
"crypto/sha256"
"strings"

"gopkg.in/yaml.v3"

Expand Down Expand Up @@ -53,15 +52,19 @@ func (d *Discriminator) FindMappingValue(key string) *low.ValueReference[string]

// Hash will return a consistent SHA256 Hash of the Discriminator object
func (d *Discriminator) Hash() [32]byte {
// calculate a hash from every property.
var f []string
// Use string builder pool
sb := low.GetStringBuilder()
defer low.PutStringBuilder(sb)

if d.PropertyName.Value != "" {
f = append(f, d.PropertyName.Value)
sb.WriteString(d.PropertyName.Value)
sb.WriteByte('|')
}

for v := range orderedmap.SortAlpha(d.Mapping.Value).ValuesFromOldest() {
f = append(f, v.Value)
sb.WriteString(v.Value)
sb.WriteByte('|')
}

return sha256.Sum256([]byte(strings.Join(f, "|")))
return sha256.Sum256([]byte(sb.String()))
}
27 changes: 18 additions & 9 deletions datamodel/low/base/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"context"
"crypto/sha256"
"fmt"
"strings"

"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
Expand Down Expand Up @@ -48,25 +47,35 @@ func (ex *Example) GetKeyNode() *yaml.Node {
return ex.KeyNode
}

// Hash will return a consistent SHA256 Hash of the Discriminator object
// Hash will return a consistent SHA256 Hash of the Example object
func (ex *Example) Hash() [32]byte {
var f []string
// Use string builder pool
sb := low.GetStringBuilder()
defer low.PutStringBuilder(sb)

if ex.Summary.Value != "" {
f = append(f, ex.Summary.Value)
sb.WriteString(ex.Summary.Value)
sb.WriteByte('|')
}
if ex.Description.Value != "" {
f = append(f, ex.Description.Value)
sb.WriteString(ex.Description.Value)
sb.WriteByte('|')
}
if ex.Value.Value != nil && !ex.Value.Value.IsZero() {
// this could be anything!
b, _ := yaml.Marshal(ex.Value.Value)
f = append(f, fmt.Sprintf("%x", sha256.Sum256(b)))
sb.WriteString(fmt.Sprintf("%x", sha256.Sum256(b)))
sb.WriteByte('|')
}
if ex.ExternalValue.Value != "" {
f = append(f, ex.ExternalValue.Value)
sb.WriteString(ex.ExternalValue.Value)
sb.WriteByte('|')
}
f = append(f, low.HashExtensions(ex.Extensions)...)
return sha256.Sum256([]byte(strings.Join(f, "|")))
for _, ext := range low.HashExtensions(ex.Extensions) {
sb.WriteString(ext)
sb.WriteByte('|')
}
return sha256.Sum256([]byte(sb.String()))
}

// Build extracts extensions and example value
Expand Down
24 changes: 17 additions & 7 deletions datamodel/low/base/external_doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package base
import (
"context"
"crypto/sha256"
"strings"

"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
Expand Down Expand Up @@ -68,13 +67,24 @@ func (ex *ExternalDoc) GetExtensions() *orderedmap.Map[low.KeyReference[string],
}

func (ex *ExternalDoc) Hash() [32]byte {
// calculate a hash from every property.
f := []string{
ex.Description.Value,
ex.URL.Value,
// Use string builder pool
sb := low.GetStringBuilder()
defer low.PutStringBuilder(sb)

if ex.Description.Value != "" {
sb.WriteString(ex.Description.Value)
sb.WriteByte('|')
}
f = append(f, low.HashExtensions(ex.Extensions)...)
return sha256.Sum256([]byte(strings.Join(f, "|")))
if ex.URL.Value != "" {
sb.WriteString(ex.URL.Value)
sb.WriteByte('|')
}

for _, ext := range low.HashExtensions(ex.Extensions) {
sb.WriteString(ext)
sb.WriteByte('|')
}
return sha256.Sum256([]byte(sb.String()))
}

// GetIndex returns the index.SpecIndex instance attached to the ExternalDoc object
Expand Down
33 changes: 22 additions & 11 deletions datamodel/low/base/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package base
import (
"context"
"crypto/sha256"
"strings"

"github.com/pb33f/libopenapi/orderedmap"
"github.com/pb33f/libopenapi/utils"
Expand Down Expand Up @@ -94,29 +93,41 @@ func (i *Info) GetContext() context.Context {

// Hash will return a consistent SHA256 Hash of the Info object
func (i *Info) Hash() [32]byte {
var f []string
// Use string builder pool
sb := low.GetStringBuilder()
defer low.PutStringBuilder(sb)

if !i.Title.IsEmpty() {
f = append(f, i.Title.Value)
sb.WriteString(i.Title.Value)
sb.WriteByte('|')
}
if !i.Summary.IsEmpty() {
f = append(f, i.Summary.Value)
sb.WriteString(i.Summary.Value)
sb.WriteByte('|')
}
if !i.Description.IsEmpty() {
f = append(f, i.Description.Value)
sb.WriteString(i.Description.Value)
sb.WriteByte('|')
}
if !i.TermsOfService.IsEmpty() {
f = append(f, i.TermsOfService.Value)
sb.WriteString(i.TermsOfService.Value)
sb.WriteByte('|')
}
if !i.Contact.IsEmpty() {
f = append(f, low.GenerateHashString(i.Contact.Value))
sb.WriteString(low.GenerateHashString(i.Contact.Value))
sb.WriteByte('|')
}
if !i.License.IsEmpty() {
f = append(f, low.GenerateHashString(i.License.Value))
sb.WriteString(low.GenerateHashString(i.License.Value))
sb.WriteByte('|')
}
if !i.Version.IsEmpty() {
f = append(f, i.Version.Value)
sb.WriteString(i.Version.Value)
sb.WriteByte('|')
}
f = append(f, low.HashExtensions(i.Extensions)...)
return sha256.Sum256([]byte(strings.Join(f, "|")))
for _, ext := range low.HashExtensions(i.Extensions) {
sb.WriteString(ext)
sb.WriteByte('|')
}
return sha256.Sum256([]byte(sb.String()))
}
19 changes: 13 additions & 6 deletions datamodel/low/base/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package base
import (
"context"
"crypto/sha256"
"strings"

"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
Expand Down Expand Up @@ -69,17 +68,25 @@ func (l *License) GetKeyNode() *yaml.Node {

// Hash will return a consistent SHA256 Hash of the License object
func (l *License) Hash() [32]byte {
var f []string
// Use string builder pool
sb := low.GetStringBuilder()
defer low.PutStringBuilder(sb)

if !l.Name.IsEmpty() {
f = append(f, l.Name.Value)
sb.WriteString(l.Name.Value)
sb.WriteByte('|')
}
if !l.URL.IsEmpty() {
f = append(f, l.URL.Value)
sb.WriteString(l.URL.Value)
sb.WriteByte('|')
}
if !l.Identifier.IsEmpty() {
f = append(f, l.Identifier.Value)
sb.WriteString(l.Identifier.Value)
sb.WriteByte('|')
}
return sha256.Sum256([]byte(strings.Join(f, "|")))

// Note: Extensions are not included in the hash for License
return sha256.Sum256([]byte(sb.String()))
}

// GetExtensions returns all extensions for License
Expand Down
Loading