Added a safety check to resolver

If the number of relatives exceeds 500  deep when resolving, libopenapi will now log a warning and escape that path from continuing. There is no reason on earth for a depth this large. It most likely indicates a circular reference that was ignored and then resolved.

Signed-off-by: quobix <dave@quobix.com>
This commit is contained in:
quobix
2023-12-03 09:15:19 -05:00
parent 82c9e21df1
commit afe5c1213b
3 changed files with 1444 additions and 1392 deletions

View File

@@ -310,7 +310,7 @@ func (resolver *Resolver) VisitReference(ref *Reference, seen map[string]bool, j
}
journey = append(journey, ref)
relatives := resolver.extractRelatives(ref, ref.Node, nil, seen, journey, resolve)
relatives := resolver.extractRelatives(ref, ref.Node, nil, seen, journey, resolve, 0)
seen = make(map[string]bool)
@@ -421,19 +421,33 @@ func (resolver *Resolver) isInfiniteCircularDependency(ref *Reference, visitedDe
func (resolver *Resolver) extractRelatives(ref *Reference, node, parent *yaml.Node,
foundRelatives map[string]bool,
journey []*Reference, resolve bool) []*Reference {
journey []*Reference, resolve bool, depth int) []*Reference {
if len(journey) > 100 {
return nil
}
// this is a safety check to prevent a stack overflow.
if depth > 500 {
def := "unknown"
if ref != nil {
def = ref.FullDefinition
}
if resolver.specIndex != nil && resolver.specIndex.logger != nil {
resolver.specIndex.logger.Warn("libopenapi resolver: relative depth exceeded 500 levels, "+
"check for circular references - resolving may be incomplete",
"reference", def)
}
return nil
}
var found []*Reference
if len(node.Content) > 0 {
for i, n := range node.Content {
if utils.IsNodeMap(n) || utils.IsNodeArray(n) {
found = append(found, resolver.extractRelatives(ref, n, node, foundRelatives, journey, resolve)...)
depth++
found = append(found, resolver.extractRelatives(ref, n, node, foundRelatives, journey, resolve, depth)...)
}
if i%2 == 0 && n.Value == "$ref" {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff