Skip to content

Commit 10b72f3

Browse files
committed
Restore HTTP URL normalization for remote refs
Re-add the HTTP URL parsing logic that handles circular references in remotely loaded specs. This was inadvertently removed but is necessary for detecting circular refs when remote specs reference each other with relative paths. Keeps the SplitRefFragment logic added to fix external circular refs.
1 parent d3a1f7a commit 10b72f3

File tree

1 file changed

+46
-28
lines changed

1 file changed

+46
-28
lines changed

datamodel/high/base/schema_proxy.go

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package base
66
import (
77
"errors"
88
"fmt"
9+
"net/url"
910
"path/filepath"
1011
"strings"
1112
"sync"
@@ -492,38 +493,55 @@ func (sp *SchemaProxy) marshalYAMLInlineInternal(ctx *InlineRenderContext) (inte
492493
}
493494

494495
for _, c := range circ {
495-
if !sp.IsReference() {
496-
continue
497-
}
498-
if sp.GetReference() == c.LoopPoint.Definition {
499-
// nope
500-
return sp.GetReferenceNode(), cirError((c.LoopPoint.Definition))
501-
}
502-
basePath := idx.GetSpecAbsolutePath()
503-
if !filepath.IsAbs(basePath) && !strings.HasPrefix(basePath, "http") {
504-
basePath, _ = filepath.Abs(basePath)
505-
}
506-
if basePath == c.LoopPoint.FullDefinition {
507-
// we loop on our-self
508-
return sp.GetReferenceNode(), cirError((c.LoopPoint.Definition))
509-
}
496+
if sp.IsReference() {
497+
if sp.GetReference() == c.LoopPoint.Definition {
498+
// nope
499+
return sp.GetReferenceNode(),
500+
cirError((c.LoopPoint.Definition))
501+
}
502+
basePath := sp.GoLow().GetIndex().GetSpecAbsolutePath()
503+
504+
if !filepath.IsAbs(basePath) && !strings.HasPrefix(basePath, "http") {
505+
basePath, _ = filepath.Abs(basePath)
506+
}
510507

511-
a := utils.ReplaceWindowsDriveWithLinuxPath(strings.Replace(c.LoopPoint.FullDefinition, basePath, "", 1))
512-
b := sp.GetReference()
508+
if basePath == c.LoopPoint.FullDefinition {
509+
// we loop on our-self
510+
return sp.GetReferenceNode(),
511+
cirError((c.LoopPoint.Definition))
512+
}
513+
a := utils.ReplaceWindowsDriveWithLinuxPath(strings.Replace(c.LoopPoint.FullDefinition, basePath, "", 1))
514+
b := sp.GetReference()
515+
if strings.HasPrefix(b, "./") {
516+
b = strings.Replace(b, "./", "/", 1) // strip any leading ./ from the reference
517+
}
518+
// if loading things in remotely and references are relative.
519+
if strings.HasPrefix(a, "http") {
520+
purl, _ := url.Parse(a)
521+
if purl != nil {
522+
specPath := filepath.Dir(purl.Path)
523+
host := fmt.Sprintf("%s://%s", purl.Scheme, purl.Host)
524+
a = strings.Replace(a, host, "", 1)
525+
a = strings.Replace(a, specPath, "", 1)
526+
}
527+
}
513528

514-
aBase, aFragment := index.SplitRefFragment(a)
515-
bBase, bFragment := index.SplitRefFragment(b)
529+
aBase, aFragment := index.SplitRefFragment(a)
530+
bBase, bFragment := index.SplitRefFragment(b)
516531

517-
if aFragment != "" && bFragment != "" && aFragment == bFragment {
518-
return sp.GetReferenceNode(), cirError((c.LoopPoint.Definition))
519-
}
532+
if aFragment != "" && bFragment != "" && aFragment == bFragment {
533+
return sp.GetReferenceNode(),
534+
cirError((c.LoopPoint.Definition))
535+
}
520536

521-
if aFragment == "" && bFragment == "" {
522-
aNorm := strings.TrimPrefix(strings.TrimPrefix(aBase, "./"), "/")
523-
bNorm := strings.TrimPrefix(strings.TrimPrefix(bBase, "./"), "/")
524-
if aNorm != "" && bNorm != "" && aNorm == bNorm {
525-
// nope
526-
return sp.GetReferenceNode(), cirError((c.LoopPoint.Definition))
537+
if aFragment == "" && bFragment == "" {
538+
aNorm := strings.TrimPrefix(strings.TrimPrefix(aBase, "./"), "/")
539+
bNorm := strings.TrimPrefix(strings.TrimPrefix(bBase, "./"), "/")
540+
if aNorm != "" && bNorm != "" && aNorm == bNorm {
541+
// nope
542+
return sp.GetReferenceNode(),
543+
cirError((c.LoopPoint.Definition))
544+
}
527545
}
528546
}
529547
}

0 commit comments

Comments
 (0)