func()

in registry/storage/validation/schema2.go [35:99]


func (v *Schema2Validator) Validate(ctx context.Context, mnfst *schema2.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 schema2.MediaTypeForeignLayer:
			// Clients download this layer from an external URL, so do not check for
			// its presence.
			if len(descriptor.URLs) == 0 {
				err = errMissingURL
			}

			for _, u := range descriptor.URLs {
				if !validURL(u, v.manifestURLs) {
					err = errInvalidURL
					break
				}
			}
		case schema2.MediaTypeManifest, schema1.MediaTypeManifest:
			var exists bool
			exists, err = v.manifestExister.Exists(ctx, descriptor.Digest)
			if err != nil || !exists {
				err = distribution.ErrBlobUnknown // just coerce to unknown.
			}

			fallthrough // double check the blob store.
		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
}