1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-29 17:36:38 +08:00

secio: buffer remainders in calls to Read()

used to return io.ErrShortBuffer, but this makes client
code much more complicated. we're already allocating
buffers when it's too large, so might as well just
keep it for later.
This commit is contained in:
Juan Batiz-Benet
2015-01-01 07:00:35 -08:00
parent a2abf108a0
commit 293ea03eb0

View File

@ -76,6 +76,9 @@ type etmReader struct {
msgio.Reader msgio.Reader
io.Closer io.Closer
// buffer
buf []byte
// params // params
msg msgio.ReadCloser // msgio for knowing where boundaries lie msg msgio.ReadCloser // msgio for knowing where boundaries lie
str cipher.Stream // the stream cipher to encrypt with str cipher.Stream // the stream cipher to encrypt with
@ -91,20 +94,35 @@ func (r *etmReader) NextMsgLen() (int, error) {
return r.msg.NextMsgLen() return r.msg.NextMsgLen()
} }
func (r *etmReader) drainBuf(buf []byte) int {
if r.buf == nil {
return 0
}
n := copy(buf, r.buf)
r.buf = r.buf[n:]
return n
}
func (r *etmReader) Read(buf []byte) (int, error) { func (r *etmReader) Read(buf []byte) (int, error) {
// first, check the buffer has enough space. // first, check if we have anything in the buffer
copied := r.drainBuf(buf)
buf = buf[copied:]
if copied > 0 {
return copied, nil
// return here to avoid complicating the rest...
// user can call io.ReadFull.
}
// check the buffer has enough space for the next msg
fullLen, err := r.msg.NextMsgLen() fullLen, err := r.msg.NextMsgLen()
if err != nil { if err != nil {
return 0, err return 0, err
} }
dataLen := fullLen - r.mac.size
if cap(buf) < dataLen {
return 0, io.ErrShortBuffer
}
buf2 := buf buf2 := buf
changed := false changed := false
// if not enough space, allocate a new buffer.
if cap(buf) < fullLen { if cap(buf) < fullLen {
buf2 = make([]byte, fullLen) buf2 = make([]byte, fullLen)
changed = true changed = true
@ -121,10 +139,15 @@ func (r *etmReader) Read(buf []byte) (int, error) {
return 0, err return 0, err
} }
buf2 = buf2[:m] buf2 = buf2[:m]
if changed { if !changed {
return copy(buf, buf2), nil return m, nil
} }
return m, nil
n = copy(buf, buf2)
if len(buf2) > len(buf) {
r.buf = buf2[len(buf):] // had some left over? save it.
}
return n, nil
} }
func (r *etmReader) ReadMsg() ([]byte, error) { func (r *etmReader) ReadMsg() ([]byte, error) {