Skip to content

Commit 4a1874b

Browse files
committed
Fixed buf_siz and added/mod unit tests to stress stream parsing.
1 parent 254b126 commit 4a1874b

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

tests/test_yajl.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,9 @@ def test_ctxIsPassedToAllCallbacks(self):
123123
"Called self.content_handler.yajl_end_map(%(ctx)s)\n"
124124
% {'ctx': repr(yajl.addressof(ctx))}
125125
)
126+
127+
def test_bufSizeLessThanZeroRaisesException(self):
128+
for buf_siz in range(-5, 1):
129+
self.failUnlessRaises(
130+
yajl.YajlConfigError,
131+
yajl.YajlParser, self.content_handler, buf_siz=buf_siz)

tests/test_yajl_c.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,26 @@ def assertSameAsGold(self, filename):
4747
got = self.out.read() #.splitlines(1)
4848
self.failUnlessEqual(expected, got)
4949

50+
def resetOutput(self):
51+
self.out.seek(0)
52+
self.out.truncate()
53+
5054
def _make_test(filename, testname):
5155
def test(self):
5256
kwargs = {}
5357
if testname.startswith('dc_'):
5458
kwargs['allow_comments'] = False
55-
parser = yajl.YajlParser(self.content_handler, **kwargs)
56-
with open(filename) as f:
57-
try:
58-
parser.parse(f)
59-
except yajl.YajlError, e:
60-
self.out.write('%s\n' %str(e).splitlines()[0])
61-
self.assertSameAsGold(filename)
59+
for buf_siz in range(32):
60+
# try out a range of buffer_sizes to stress stream parsing
61+
kwargs['buf_siz'] = buf_siz + 1
62+
parser = yajl.YajlParser(self.content_handler, **kwargs)
63+
with open(filename) as f:
64+
try:
65+
parser.parse(f)
66+
except yajl.YajlError, e:
67+
self.out.write('%s\n' %str(e).splitlines()[0])
68+
self.assertSameAsGold(filename)
69+
self.resetOutput()
6270
return test
6371

6472
def _add_methods():

yajl/yajl_parse.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ def __init__(self, content_handler, allow_comments=True, check_utf8=True, buf_si
126126
`check_utf8` specifies whether utf8 charachters are allowed in the document
127127
`buf_siz` the number of bytes to process from the input stream at a time
128128
'''
129+
# input validation
130+
if buf_siz <= 0:
131+
raise YajlConfigError('Buffer Size (buf_siz) must be set > 0')
129132
c_funcs = (
130133
YAJL_NULL, YAJL_BOOL, YAJL_INT, YAJL_DBL, YAJL_NUM,
131134
YAJL_STR, YAJL_SDCT, YAJL_DCTK, YAJL_EDCT, YAJL_SARR,
@@ -189,7 +192,6 @@ def parse(self, f=sys.stdin, ctx=None):
189192
'''Function to parse a JSON stream.
190193
Parameters:
191194
`f` : file stream to read from
192-
`buf_size` : size in bytes of read buffer
193195
`ctx` : A ctypes pointer that will be passed to
194196
all callback functions as the first param
195197
@@ -201,7 +203,7 @@ def parse(self, f=sys.stdin, ctx=None):
201203
hand = yajl.yajl_alloc( byref(self.callbacks), byref(self.cfg), None, ctx)
202204
try:
203205
while 1:
204-
fileData = f.read(self.buf_siz-1)
206+
fileData = f.read(self.buf_siz)
205207
if not fileData:
206208
stat = yajl.yajl_parse_complete(hand)
207209
else:

0 commit comments

Comments
 (0)