Skip to content
This repository was archived by the owner on Jun 30, 2022. It is now read-only.

Commit c731121

Browse files
committed
Fix buffer overruns in fast OutputStream implementaion
----Release Notes---- [] ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=124285266
1 parent ba23cca commit c731121

2 files changed

Lines changed: 15 additions & 4 deletions

File tree

google/cloud/dataflow/coders/stream.pyx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ cdef class OutputStream(object):
2525
self.size = 1024
2626
self.pos = 0
2727
self.data = <char*>libc.stdlib.malloc(self.size)
28+
assert self.data, "OutputStream malloc failed."
2829

2930
def __dealloc__(self):
3031
if self.data:
@@ -34,13 +35,13 @@ cdef class OutputStream(object):
3435
cdef size_t blen = len(b)
3536
if nested:
3637
self.write_var_int64(blen)
37-
if blen > self.size - self.pos:
38+
if self.size < self.pos + blen:
3839
self.extend(blen)
3940
libc.string.memcpy(self.data + self.pos, <char*>b, blen)
4041
self.pos += blen
4142

4243
cpdef write_byte(self, unsigned char val):
43-
if self.size <= self.pos:
44+
if self.size < self.pos + 1:
4445
self.extend(1)
4546
self.data[self.pos] = val
4647
self.pos += 1
@@ -60,7 +61,7 @@ cdef class OutputStream(object):
6061

6162
cpdef write_bigendian_int64(self, libc.stdint.int64_t signed_v):
6263
cdef libc.stdint.uint64_t v = signed_v
63-
if self.size < self.pos - 8:
64+
if self.size < self.pos + 8:
6465
self.extend(8)
6566
self.data[self.pos ] = <unsigned char>(v >> 56)
6667
self.data[self.pos + 1] = <unsigned char>(v >> 48)
@@ -74,7 +75,7 @@ cdef class OutputStream(object):
7475

7576
cpdef write_bigendian_int32(self, libc.stdint.int32_t signed_v):
7677
cdef libc.stdint.uint32_t v = signed_v
77-
if self.size < self.pos - 4:
78+
if self.size < self.pos + 4:
7879
self.extend(4)
7980
self.data[self.pos ] = <unsigned char>(v >> 24)
8081
self.data[self.pos + 1] = <unsigned char>(v >> 16)
@@ -92,6 +93,7 @@ cdef class OutputStream(object):
9293
while missing > self.size - self.pos:
9394
self.size *= 2
9495
self.data = <char*>libc.stdlib.realloc(self.data, self.size)
96+
assert self.data, "OutputStream realloc failed."
9597

9698

9799
cdef class ByteCountingOutputStream(OutputStream):

google/cloud/dataflow/coders/stream_test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ def test_read_write_byte(self):
5656
self.assertEquals(0, in_s.read_byte())
5757
self.assertEquals(0xFF, in_s.read_byte())
5858

59+
def test_read_write_large(self):
60+
values = range(4 * 1024)
61+
out_s = self.OutputStream()
62+
for v in values:
63+
out_s.write_bigendian_int64(v)
64+
in_s = self.InputStream(out_s.get())
65+
for v in values:
66+
self.assertEquals(v, in_s.read_bigendian_int64())
67+
5968
def run_read_write_var_int64(self, values):
6069
out_s = self.OutputStream()
6170
for v in values:

0 commit comments

Comments
 (0)