[#42] object/transformer: Fix incorrect checksums of parent object

In previous implementations object size limiter left checksums of parent
object payload unset. This was caused by the closure that written calculated
checksums to the child object instead of parent one.

Construct payload checksum writers in separate function in order to prevent
closure bug.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-09-24 15:22:59 +03:00 committed by Alex Vanin
parent 3038c6cc5c
commit a433f9dd85

View file

@ -99,40 +99,7 @@ func (s *payloadSizeLimiter) initializeCurrent() {
s.target = s.targetInit() s.target = s.targetInit()
// create payload hashers // create payload hashers
s.currentHashers = []*payloadChecksumHasher{ s.currentHashers = payloadHashersForObject(s.current)
{
hasher: sha256.New(),
checksumWriter: func(cs []byte) {
if ln := len(cs); ln != sha256.Size {
panic(fmt.Sprintf("wrong checksum length: expected %d, has %d", ln, sha256.Size))
}
csSHA := [sha256.Size]byte{}
copy(csSHA[:], cs)
checksum := pkg.NewChecksum()
checksum.SetSHA256(csSHA)
s.current.SetPayloadChecksum(checksum)
},
},
{
hasher: tz.New(),
checksumWriter: func(cs []byte) {
if ln := len(cs); ln != tzChecksumSize {
panic(fmt.Sprintf("wrong checksum length: expected %d, has %d", ln, tzChecksumSize))
}
csTZ := [tzChecksumSize]byte{}
copy(csTZ[:], cs)
checksum := pkg.NewChecksum()
checksum.SetTillichZemor(csTZ)
s.current.SetPayloadHomomorphicHash(checksum)
},
},
}
// compose multi-writer from target and all payload hashers // compose multi-writer from target and all payload hashers
ws := make([]io.Writer, 0, 1+len(s.currentHashers)+len(s.parentHashers)) ws := make([]io.Writer, 0, 1+len(s.currentHashers)+len(s.parentHashers))
@ -150,6 +117,43 @@ func (s *payloadSizeLimiter) initializeCurrent() {
s.chunkWriter = io.MultiWriter(ws...) s.chunkWriter = io.MultiWriter(ws...)
} }
func payloadHashersForObject(obj *object.RawObject) []*payloadChecksumHasher {
return []*payloadChecksumHasher{
{
hasher: sha256.New(),
checksumWriter: func(cs []byte) {
if ln := len(cs); ln != sha256.Size {
panic(fmt.Sprintf("wrong checksum length: expected %d, has %d", ln, sha256.Size))
}
csSHA := [sha256.Size]byte{}
copy(csSHA[:], cs)
checksum := pkg.NewChecksum()
checksum.SetSHA256(csSHA)
obj.SetPayloadChecksum(checksum)
},
},
{
hasher: tz.New(),
checksumWriter: func(cs []byte) {
if ln := len(cs); ln != tzChecksumSize {
panic(fmt.Sprintf("wrong checksum length: expected %d, has %d", ln, tzChecksumSize))
}
csTZ := [tzChecksumSize]byte{}
copy(csTZ[:], cs)
checksum := pkg.NewChecksum()
checksum.SetTillichZemor(csTZ)
obj.SetPayloadHomomorphicHash(checksum)
},
},
}
}
func (s *payloadSizeLimiter) release(close bool) (*AccessIdentifiers, error) { func (s *payloadSizeLimiter) release(close bool) (*AccessIdentifiers, error) {
// Arg close is true only from Close method. // Arg close is true only from Close method.
// We finalize parent and generate linking objects only if it is more // We finalize parent and generate linking objects only if it is more