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)
 }