You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by je...@apache.org on 2016/05/28 11:31:56 UTC
thrift git commit: THRIFT-3805 Golang server susceptible to memory
spike from malformed message Client: Go Patch: Michael Scott Leuthaeuser
Repository: thrift
Updated Branches:
refs/heads/master 1fa95f53b -> 5f06802c7
THRIFT-3805 Golang server susceptible to memory spike from malformed message
Client: Go
Patch: Michael Scott Leuthaeuser <sc...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/5f06802c
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/5f06802c
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/5f06802c
Branch: refs/heads/master
Commit: 5f06802c73647e1050df532bddfb49f1ccb3bc1b
Parents: 1fa95f5
Author: Michael Scott Leuthaeuser <sc...@gmail.com>
Authored: Sat May 28 13:27:39 2016 +0200
Committer: Jens Geyer <je...@apache.org>
Committed: Sat May 28 13:31:33 2016 +0200
----------------------------------------------------------------------
lib/go/thrift/binary_protocol.go | 37 ++++++++++++++++++++++++++++-------
1 file changed, 30 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/thrift/blob/5f06802c/lib/go/thrift/binary_protocol.go
----------------------------------------------------------------------
diff --git a/lib/go/thrift/binary_protocol.go b/lib/go/thrift/binary_protocol.go
index e1b4056..690d341 100644
--- a/lib/go/thrift/binary_protocol.go
+++ b/lib/go/thrift/binary_protocol.go
@@ -20,6 +20,7 @@
package thrift
import (
+ "bytes"
"encoding/binary"
"errors"
"fmt"
@@ -473,6 +474,8 @@ func (p *TBinaryProtocol) readAll(buf []byte) error {
return NewTProtocolException(err)
}
+const readLimit = 32768
+
func (p *TBinaryProtocol) readStringBody(size int32) (value string, err error) {
if size < 0 {
return "", nil
@@ -480,12 +483,32 @@ func (p *TBinaryProtocol) readStringBody(size int32) (value string, err error) {
if uint64(size) > p.trans.RemainingBytes() {
return "", invalidDataLength
}
- var buf []byte
- if int(size) <= len(p.buffer) {
- buf = p.buffer[0:size]
- } else {
- buf = make([]byte, size)
+
+ var (
+ buf bytes.Buffer
+ e error
+ b []byte
+ )
+
+ switch {
+ case int(size) <= len(p.buffer):
+ b = p.buffer[:size] // avoids allocation for small reads
+ case int(size) < readLimit:
+ b = make([]byte, size)
+ default:
+ b = make([]byte, readLimit)
+ }
+
+ for size > 0 {
+ _, e = io.ReadFull(p.trans, b)
+ buf.Write(b)
+ if e != nil {
+ break
+ }
+ size -= readLimit
+ if size < readLimit && size > 0 {
+ b = b[:size]
+ }
}
- _, e := io.ReadFull(p.trans, buf)
- return string(buf), NewTProtocolException(e)
+ return buf.String(), NewTProtocolException(e)
}