func()

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
}