From 66f9532857beae2424b8ab8c2a0e6ad9f4544da7 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Fri, 18 Dec 2020 14:48:28 +0300 Subject: [PATCH] [#264] object/get: Check parent address in linking/last child Signed-off-by: Leonard Lyubich --- go.sum | Bin 60710 -> 60804 bytes pkg/services/object/get/assemble.go | 19 ++++------------ pkg/services/object/get/exec.go | 34 ++++++++++++++++++++++++---- pkg/services/object/get/get_test.go | 1 + 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/go.sum b/go.sum index 702409893b6474a0a3b2403dc473e4241b0a699e..b6d67571c2a78aebc765d522a2880f4a4be2dd81 100644 GIT binary patch delta 66 zcmZ2>i@D`C^9EaMeT57|D}Cnx({zhc{V*?&%&hd(6lZ;()bu=KC&whm#PERh)a3FA WCr_8Ea?`y0$s28jH!E7RZUO-OIu_Uf delta 18 acmZp<&AjXu^9Eb%$?|I4o0nPN+Xw(lvj`Lb diff --git a/pkg/services/object/get/assemble.go b/pkg/services/object/get/assemble.go index 228180d68..8a1f9efe3 100644 --- a/pkg/services/object/get/assemble.go +++ b/pkg/services/object/get/assemble.go @@ -26,7 +26,7 @@ func (exec *execCtx) assemble() { if len(children) > 0 { if exec.ctxRange() == nil { if ok := exec.writeCollectedHeader(); ok { - exec.overtakePayloadDirectly(children, nil) + exec.overtakePayloadDirectly(children, nil, true) } } else { // TODO: choose one-by-one restoring algorithm according to size @@ -59,7 +59,7 @@ func (exec *execCtx) initFromChild(id *objectSDK.ID) (prev *objectSDK.ID, childr log.Debug("starting assembling from child") - child, ok := exec.getChild(id, nil) + child, ok := exec.getChild(id, nil, true) if !ok { return } @@ -70,15 +70,6 @@ func (exec *execCtx) initFromChild(id *objectSDK.ID) (prev *objectSDK.ID, childr log.Debug("received child with empty parent") - return - } else if !equalAddresses(par.Address(), exec.address()) { - exec.status = statusUndefined - - log.Debug("parent address in child object differs", - zap.Stringer("expected", exec.address()), - zap.Stringer("received", par.Address()), - ) - return } @@ -122,7 +113,7 @@ func (exec *execCtx) initFromChild(id *objectSDK.ID) (prev *objectSDK.ID, childr return child.PreviousID(), child.Children() } -func (exec *execCtx) overtakePayloadDirectly(children []*objectSDK.ID, rngs []*objectSDK.Range) { +func (exec *execCtx) overtakePayloadDirectly(children []*objectSDK.ID, rngs []*objectSDK.Range, checkRight bool) { withRng := len(rngs) > 0 for i := range children { @@ -131,7 +122,7 @@ func (exec *execCtx) overtakePayloadDirectly(children []*objectSDK.ID, rngs []*o r = rngs[i] } - child, ok := exec.getChild(children[i], r) + child, ok := exec.getChild(children[i], r, !withRng && checkRight) if !ok { return } @@ -162,7 +153,7 @@ func (exec *execCtx) overtakePayloadInReverse(prev *objectSDK.ID) bool { } } - exec.overtakePayloadDirectly(chain, rngs) + exec.overtakePayloadDirectly(chain, rngs, false) exec.status = statusOK exec.err = nil diff --git a/pkg/services/object/get/exec.go b/pkg/services/object/get/exec.go index 84a89cecb..05f8ff89d 100644 --- a/pkg/services/object/get/exec.go +++ b/pkg/services/object/get/exec.go @@ -3,6 +3,7 @@ package getsvc import ( "context" "crypto/ecdsa" + "errors" "github.com/nspcc-dev/neofs-api-go/pkg/client" "github.com/nspcc-dev/neofs-api-go/pkg/container" @@ -95,6 +96,11 @@ func (exec execCtx) address() *objectSDK.Address { return exec.prm.Address() } +func (exec execCtx) isChild(obj *object.Object) bool { + par := obj.GetParent() + return par != nil && equalAddresses(exec.address(), par.Address()) +} + func (exec execCtx) key() *ecdsa.PrivateKey { return exec.prm.common.PrivateKey() } @@ -147,7 +153,7 @@ func (exec *execCtx) generateTraverser(addr *objectSDK.Address) (*placement.Trav } } -func (exec *execCtx) getChild(id *objectSDK.ID, rng *objectSDK.Range) (*object.Object, bool) { +func (exec *execCtx) getChild(id *objectSDK.ID, rng *objectSDK.Range, withHdr bool) (*object.Object, bool) { w := NewSimpleObjectWriter() p := exec.prm @@ -163,7 +169,17 @@ func (exec *execCtx) getChild(id *objectSDK.ID, rng *objectSDK.Range) (*object.O exec.statusError = exec.svc.get(exec.context(), p.commonPrm, withPayloadRange(rng)) - return w.Object(), exec.status == statusOK + child := w.Object() + ok := exec.status == statusOK + + if ok && withHdr && !exec.isChild(child) { + exec.status = statusUndefined + exec.err = errors.New("wrong child header") + + exec.log.Debug("parent address in child object differs") + } + + return child, ok } func (exec *execCtx) headChild(id *objectSDK.ID) (*object.Object, bool) { @@ -196,10 +212,18 @@ func (exec *execCtx) headChild(id *objectSDK.ID) (*object.Object, bool) { return nil, false case err == nil: - exec.status = statusOK - exec.err = nil + child := w.Object() - return w.Object(), true + if child.ParentID() != nil && !exec.isChild(child) { + exec.status = statusUndefined + + exec.log.Debug("parent address in child object differs") + } else { + exec.status = statusOK + exec.err = nil + } + + return child, true } } diff --git a/pkg/services/object/get/get_test.go b/pkg/services/object/get/get_test.go index 5475c4187..6bb2d78a6 100644 --- a/pkg/services/object/get/get_test.go +++ b/pkg/services/object/get/get_test.go @@ -826,6 +826,7 @@ func TestGetRemoteSmall(t *testing.T) { children, childIDs, payload := generateChain(2, cid) srcObj.SetPayload(payload) srcObj.SetPayloadSize(uint64(len(payload))) + children[len(children)-1].SetParent(srcObj.Object().SDK()) linkAddr := objectSDK.NewAddress() linkAddr.SetContainerID(cid)