[#1286] services/object: Validate object when created with sesssion token
All fields set by a user should be verified. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
c6a9c5cd8c
commit
5736b834c3
4 changed files with 89 additions and 71 deletions
|
@ -14,11 +14,14 @@ import (
|
|||
"github.com/nspcc-dev/tzhash/tz"
|
||||
)
|
||||
|
||||
// validatingTarget validates object format and content.
|
||||
type validatingTarget struct {
|
||||
nextTarget transformer.ObjectTarget
|
||||
|
||||
fmt *object.FormatValidator
|
||||
|
||||
unpreparedObject bool
|
||||
|
||||
hash hash.Hash
|
||||
|
||||
checksum []byte
|
||||
|
@ -40,29 +43,31 @@ func (t *validatingTarget) WriteHeader(obj *objectSDK.Object) error {
|
|||
t.payloadSz = obj.PayloadSize()
|
||||
chunkLn := uint64(len(obj.Payload()))
|
||||
|
||||
// check chunk size
|
||||
if chunkLn > t.payloadSz {
|
||||
return ErrWrongPayloadSize
|
||||
if !t.unpreparedObject {
|
||||
// check chunk size
|
||||
if chunkLn > t.payloadSz {
|
||||
return ErrWrongPayloadSize
|
||||
}
|
||||
|
||||
// check payload size limit
|
||||
if t.payloadSz > t.maxPayloadSz {
|
||||
return ErrExceedingMaxSize
|
||||
}
|
||||
|
||||
cs := obj.PayloadChecksum()
|
||||
switch typ := cs.Type(); typ {
|
||||
default:
|
||||
return fmt.Errorf("(%T) unsupported payload checksum type %v", t, typ)
|
||||
case checksum.SHA256:
|
||||
t.hash = sha256.New()
|
||||
case checksum.TZ:
|
||||
t.hash = tz.New()
|
||||
}
|
||||
|
||||
t.checksum = cs.Sum()
|
||||
}
|
||||
|
||||
// check payload size limit
|
||||
if t.payloadSz > t.maxPayloadSz {
|
||||
return ErrExceedingMaxSize
|
||||
}
|
||||
|
||||
cs := obj.PayloadChecksum()
|
||||
switch typ := cs.Type(); typ {
|
||||
default:
|
||||
return fmt.Errorf("(%T) unsupported payload checksum type %v", t, typ)
|
||||
case checksum.SHA256:
|
||||
t.hash = sha256.New()
|
||||
case checksum.TZ:
|
||||
t.hash = tz.New()
|
||||
}
|
||||
|
||||
t.checksum = cs.Sum()
|
||||
|
||||
if err := t.fmt.Validate(obj); err != nil {
|
||||
if err := t.fmt.Validate(obj, t.unpreparedObject); err != nil {
|
||||
return fmt.Errorf("(%T) coult not validate object format: %w", t, err)
|
||||
}
|
||||
|
||||
|
@ -71,11 +76,13 @@ func (t *validatingTarget) WriteHeader(obj *objectSDK.Object) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// update written bytes
|
||||
//
|
||||
// Note: we MUST NOT add obj.PayloadSize() since obj
|
||||
// can carry only the chunk of the full payload
|
||||
t.writtenPayload += chunkLn
|
||||
if !t.unpreparedObject {
|
||||
// update written bytes
|
||||
//
|
||||
// Note: we MUST NOT add obj.PayloadSize() since obj
|
||||
// can carry only the chunk of the full payload
|
||||
t.writtenPayload += chunkLn
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -83,14 +90,16 @@ func (t *validatingTarget) WriteHeader(obj *objectSDK.Object) error {
|
|||
func (t *validatingTarget) Write(p []byte) (n int, err error) {
|
||||
chunkLn := uint64(len(p))
|
||||
|
||||
// check if new chunk will overflow payload size
|
||||
if t.writtenPayload+chunkLn > t.payloadSz {
|
||||
return 0, ErrWrongPayloadSize
|
||||
}
|
||||
if !t.unpreparedObject {
|
||||
// check if new chunk will overflow payload size
|
||||
if t.writtenPayload+chunkLn > t.payloadSz {
|
||||
return 0, ErrWrongPayloadSize
|
||||
}
|
||||
|
||||
_, err = t.hash.Write(p)
|
||||
if err != nil {
|
||||
return
|
||||
_, err = t.hash.Write(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
n, err = t.nextTarget.Write(p)
|
||||
|
@ -102,13 +111,15 @@ func (t *validatingTarget) Write(p []byte) (n int, err error) {
|
|||
}
|
||||
|
||||
func (t *validatingTarget) Close() (*transformer.AccessIdentifiers, error) {
|
||||
// check payload size correctness
|
||||
if t.payloadSz != t.writtenPayload {
|
||||
return nil, ErrWrongPayloadSize
|
||||
}
|
||||
if !t.unpreparedObject {
|
||||
// check payload size correctness
|
||||
if t.payloadSz != t.writtenPayload {
|
||||
return nil, ErrWrongPayloadSize
|
||||
}
|
||||
|
||||
if !bytes.Equal(t.hash.Sum(nil), t.checksum) {
|
||||
return nil, fmt.Errorf("(%T) incorrect payload checksum", t)
|
||||
if !bytes.Equal(t.hash.Sum(nil), t.checksum) {
|
||||
return nil, fmt.Errorf("(%T) incorrect payload checksum", t)
|
||||
}
|
||||
}
|
||||
|
||||
return t.nextTarget.Close()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue