Bound remote asset content verification
This commit is contained in:
@@ -77,11 +77,11 @@ func inspectRemoteAssets(ctx context.Context, backend forge.Backend, releaseHand
|
||||
case 0:
|
||||
observation.State = AssetMissing
|
||||
case 1:
|
||||
digest, err := remoteAssetDigest(ctx, backend, matches[0].Handle)
|
||||
digest, sizeMatches, err := remoteAssetDigest(ctx, backend, matches[0].Handle, item.Size)
|
||||
if err != nil {
|
||||
observation.State = AssetUnverifiable
|
||||
observation.Err = err
|
||||
} else if digest == item.SHA256 {
|
||||
} else if sizeMatches && digest == item.SHA256 {
|
||||
observation.State = AssetMatching
|
||||
} else {
|
||||
observation.State = AssetConflicting
|
||||
@@ -99,18 +99,40 @@ func inspectRemoteAssets(ctx context.Context, backend forge.Backend, releaseHand
|
||||
return inspection, nil
|
||||
}
|
||||
|
||||
func remoteAssetDigest(ctx context.Context, backend forge.Backend, handle any) (string, error) {
|
||||
func remoteAssetDigest(ctx context.Context, backend forge.Backend, handle any, expectedSize int64) (string, bool, error) {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
stream, err := backend.OpenAsset(ctx, handle)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", false, err
|
||||
}
|
||||
hasher := sha256.New()
|
||||
_, readErr := io.Copy(hasher, stream)
|
||||
closeErr := stream.Close()
|
||||
if err := errors.Join(readErr, closeErr); err != nil {
|
||||
return "", &forge.Failure{Kind: forge.FailureUnverifiable, Err: err}
|
||||
read, readErr := io.Copy(hasher, io.LimitReader(stream, expectedSize))
|
||||
excess := false
|
||||
if readErr == nil && read == expectedSize {
|
||||
var probe [1]byte
|
||||
for attempts := 0; ; attempts++ {
|
||||
var n int
|
||||
n, readErr = stream.Read(probe[:])
|
||||
excess = n != 0
|
||||
if readErr != nil || excess {
|
||||
if readErr == io.EOF {
|
||||
readErr = nil
|
||||
}
|
||||
break
|
||||
}
|
||||
if attempts == 99 {
|
||||
readErr = io.ErrNoProgress
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return hex.EncodeToString(hasher.Sum(nil)), nil
|
||||
closeErr := stream.Close()
|
||||
if err := errors.Join(readErr, closeErr, ctx.Err()); err != nil {
|
||||
return "", false, &forge.Failure{Kind: forge.FailureUnverifiable, Err: err}
|
||||
}
|
||||
return hex.EncodeToString(hasher.Sum(nil)), read == expectedSize && !excess, nil
|
||||
}
|
||||
|
||||
func uploadMissingAssets(ctx context.Context, backend forge.Backend, releaseHandle any, inspection Inspection) (result UploadResult, err error) {
|
||||
|
||||
Reference in New Issue
Block a user