Skip to content

Commit 58d90fa

Browse files
committed
bounds check when reading from the buffer
1 parent f42867a commit 58d90fa

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

frame.go

+41-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"io"
1010
"net"
11+
"runtime"
1112
"sync"
1213
"time"
1314
)
@@ -371,12 +372,10 @@ func (f *framer) parseFrame() (frame frame, err error) {
371372

372373
defer func() {
373374
if r := recover(); r != nil {
374-
if perr, ok := r.(error); ok {
375-
err = perr
376-
return
375+
if _, ok := r.(runtime.Error); ok {
376+
panic(r)
377377
}
378-
379-
panic(r)
378+
err = r.(error)
380379
}
381380
}()
382381

@@ -1161,18 +1160,28 @@ func (f *framer) readByte() byte {
11611160
}
11621161

11631162
func (f *framer) readInt() (n int) {
1163+
if len(f.rbuf) < 4 {
1164+
panic(fmt.Errorf("not enough bytes in buffer to read int require 4 got: %d", len(f.rbuf)))
1165+
}
1166+
11641167
n = int(int32(f.rbuf[0])<<24 | int32(f.rbuf[1])<<16 | int32(f.rbuf[2])<<8 | int32(f.rbuf[3]))
11651168
f.rbuf = f.rbuf[4:]
11661169
return
11671170
}
11681171

11691172
func (f *framer) readShort() (n uint16) {
1173+
if len(f.rbuf) < 2 {
1174+
panic(fmt.Errorf("not enough bytes in buffer to read short require 2 got: %d", len(f.rbuf)))
1175+
}
11701176
n = uint16(f.rbuf[0])<<8 | uint16(f.rbuf[1])
11711177
f.rbuf = f.rbuf[2:]
11721178
return
11731179
}
11741180

11751181
func (f *framer) readLong() (n int64) {
1182+
if len(f.rbuf) < 8 {
1183+
panic(fmt.Errorf("not enough bytes in buffer to read long require 8 got: %d", len(f.rbuf)))
1184+
}
11761185
n = int64(f.rbuf[0])<<56 | int64(f.rbuf[1])<<48 | int64(f.rbuf[2])<<40 | int64(f.rbuf[3])<<32 |
11771186
int64(f.rbuf[4])<<24 | int64(f.rbuf[5])<<16 | int64(f.rbuf[6])<<8 | int64(f.rbuf[7])
11781187
f.rbuf = f.rbuf[8:]
@@ -1181,19 +1190,33 @@ func (f *framer) readLong() (n int64) {
11811190

11821191
func (f *framer) readString() (s string) {
11831192
size := f.readShort()
1193+
1194+
if len(f.rbuf) < int(size) {
1195+
panic(fmt.Errorf("not enough bytes in buffer to read string require %d got: %d", size, len(f.rbuf)))
1196+
}
1197+
11841198
s = string(f.rbuf[:size])
11851199
f.rbuf = f.rbuf[size:]
11861200
return
11871201
}
11881202

11891203
func (f *framer) readLongString() (s string) {
11901204
size := f.readInt()
1205+
1206+
if len(f.rbuf) < size {
1207+
panic(fmt.Errorf("not enough bytes in buffer to read long string require %d got: %d", size, len(f.rbuf)))
1208+
}
1209+
11911210
s = string(f.rbuf[:size])
11921211
f.rbuf = f.rbuf[size:]
11931212
return
11941213
}
11951214

11961215
func (f *framer) readUUID() *UUID {
1216+
if len(f.rbuf) < 16 {
1217+
panic(fmt.Errorf("not enough bytes in buffer to read uuid require %d got: %d", 16, len(f.rbuf)))
1218+
}
1219+
11971220
// TODO: how to handle this error, if it is a uuid, then sureley, problems?
11981221
u, _ := UUIDFromBytes(f.rbuf[:16])
11991222
f.rbuf = f.rbuf[16:]
@@ -1217,6 +1240,10 @@ func (f *framer) readBytes() []byte {
12171240
return nil
12181241
}
12191242

1243+
if len(f.rbuf) < size {
1244+
panic(fmt.Errorf("not enough bytes in buffer to read bytes require %d got: %d", size, len(f.rbuf)))
1245+
}
1246+
12201247
// we cant make assumptions about the length of the life of the supplied byte
12211248
// slice so we defensivly copy it out of the underlying buffer. This has the
12221249
// downside of increasing allocs per read but will provide much greater memory
@@ -1240,11 +1267,19 @@ func (f *framer) readShortBytes() []byte {
12401267
}
12411268

12421269
func (f *framer) readInet() (net.IP, int) {
1270+
if len(f.rbuf) < 1 {
1271+
panic(fmt.Errorf("not enough bytes in buffer to read inet size require %d got: %d", 1, len(f.rbuf)))
1272+
}
1273+
12431274
size := f.rbuf[0]
12441275
f.rbuf = f.rbuf[1:]
12451276

12461277
if !(size == 4 || size == 16) {
1247-
panic(fmt.Sprintf("invalid IP size: %d", size))
1278+
panic(fmt.Errorf("invalid IP size: %d", size))
1279+
}
1280+
1281+
if len(f.rbuf) < 1 {
1282+
panic(fmt.Errorf("not enough bytes in buffer to read inet require %d got: %d", size, len(f.rbuf)))
12481283
}
12491284

12501285
ip := make([]byte, size)

0 commit comments

Comments
 (0)