in registry/storage/validation/oci.go [36:98]
func (v *OCIValidator) Validate(ctx context.Context, mnfst *ocischema.DeserializedManifest) error {
var errs distribution.ErrManifestVerification
if mnfst.Manifest.SchemaVersion != 2 {
return fmt.Errorf("unrecognized manifest schema version %d", mnfst.Manifest.SchemaVersion)
}
if err := v.exceedsPayloadSizeLimit(mnfst); err != nil {
errs = append(errs, err)
return errs
}
if err := v.exceedsRefLimit(mnfst); err != nil {
errs = append(errs, err)
return errs
}
for _, descriptor := range mnfst.References() {
var err error
switch descriptor.MediaType {
case v1.MediaTypeImageLayer, v1.MediaTypeImageLayerGzip, v1.MediaTypeImageLayerNonDistributable, v1.MediaTypeImageLayerNonDistributableGzip:
for _, u := range descriptor.URLs {
if !validURL(u, v.manifestURLs) {
err = errInvalidURL
break
}
}
if err == nil && len(descriptor.URLs) == 0 {
// If no URLs, require that the blob exists
_, err = v.blobStatter.Stat(ctx, descriptor.Digest)
}
case v1.MediaTypeImageManifest, schema2.MediaTypeManifest:
var exists bool
exists, err = v.manifestExister.Exists(ctx, descriptor.Digest)
if err != nil || !exists {
err = distribution.ErrBlobUnknown // just coerce to unknown.
}
default:
// forward all else to blob storage
if len(descriptor.URLs) == 0 {
_, err = v.blobStatter.Stat(ctx, descriptor.Digest)
}
}
if err != nil {
if err != distribution.ErrBlobUnknown {
errs = append(errs, err)
}
// On error here, we always append unknown blob errors.
errs = append(errs, distribution.ErrManifestBlobUnknown{Digest: descriptor.Digest})
}
}
if len(errs) != 0 {
return errs
}
return nil
}