diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c1023584c455e672db4c91da4776f733bd4525d..decc6d419f78789f1b85a72a6283ebdfdc534d32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,4 +3,11 @@ here's only the changelog for the version in development # v1.5 -* _TBA_ +* fixed a bug with wrong type of dict and string was chosen + for a dict which contains exactly 65535 keys. + Since this is rare in production, it can wait. + MiniJSON is still generated correctly. +* fixed a bug with dumping strings longer than 255 characters + would not return a length +* fixed a bug with unserializing some strings + diff --git a/minijson/routines.pyx b/minijson/routines.pyx index 5e108e78357620796a20275b5a81dc45f4a4ea23..48a8f2cf6170520159096268472376a2a9a67749 100644 --- a/minijson/routines.pyx +++ b/minijson/routines.pyx @@ -209,7 +209,7 @@ cpdef tuple parse(bytes data, int starting_position): return offset+2, e_dict elif value_type == 13: string_length, = STRUCT_H.unpack(data[starting_position+1:starting_position+3]) - return 3+string_length, data[starting_position+2:starting_position+string_length+1].decode('utf-8') + return 3+string_length, data[starting_position+3:starting_position+string_length+3].decode('utf-8') elif value_type == 14: string_length, = STRUCT_L.unpack(data[starting_position+1:starting_position+5]) return 5+string_length, data[starting_position+5:starting_position+string_length+5].decode('utf-8') @@ -277,18 +277,20 @@ cpdef int dump(object data, cio: io.BytesIO) except -1: cio.write(bytearray([0x80 | length])) cio.write(data.encode('utf-8')) return 1+length - elif length < 255: + elif length <= 0xFF: cio.write(bytearray([0, length])) cio.write(data.encode('utf-8')) return 2+length - elif length < 65535: + elif length <= 0xFFFF: cio.write(b'\x0D') cio.write(STRUCT_H.pack(length)) cio.write(data.encode('utf-8')) - elif length < 0xFFFFFFFF: + return 3+length + elif length <= 0xFFFFFFFF: cio.write(b'\x0E') cio.write(STRUCT_L.pack(length)) cio.write(data.encode('utf-8')) + return 5+length else: raise EncodingError('String is too long!') elif isinstance(data, int): @@ -375,20 +377,22 @@ cpdef int dump(object data, cio: io.BytesIO) except -1: raise EncodingError('Keys have to be strings!') from e return length else: - if length < 16: + if length <= 0xF: cio.write(bytearray([0b01100000 | length])) offset = 1 - elif length < 256: + elif length <= 0xFF: cio.write(bytearray([20, length])) offset = 2 - elif length < 0xFFFF: + elif length <= 0xFFFF: cio.write(b'\x15') cio.write(STRUCT_H.pack(length)) offset = 3 - else: + elif length <= 0xFFFFFFFF: cio.write(b'\x13') cio.write(STRUCT_L.pack(length)) offset = 5 + else: + raise EncodingError('Too long of a string!') for key, value in data.items(): offset += dump(key, cio) diff --git a/setup.py b/setup.py index b02e9a8945702b4c5c3eb9fd83a5abecf2817f52..bdfafc349781202a764091536f3f80634f450106 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ if 'DEBUG' in os.environ: directives['embedsignature'] = True -setup(version='1.5a1', +setup(version='1.5', packages=find_packages(include=['minijson', 'minijson.*']), ext_modules=build([Multibuild('minijson', find_pyx('minijson'), dont_snakehouse=dont_snakehouse), ], diff --git a/tests/test_minijson.py b/tests/test_minijson.py index d8392483957d2489edc2c9ff590b47e87266db43..7737d9721ab380b7f3d46223054e8673085ba78f 100644 --- a/tests/test_minijson.py +++ b/tests/test_minijson.py @@ -71,6 +71,12 @@ class TestMiniJSON(unittest.TestCase): a.append(i*2) self.assertSameAfterDumpsAndLoads(a) + def test_negatives(self): + self.assertSameAfterDumpsAndLoads(-1) + self.assertSameAfterDumpsAndLoads(-259) + self.assertSameAfterDumpsAndLoads(-0x7FFF) + self.assertSameAfterDumpsAndLoads(-0xFFFF) + def test_dumps(self): v = {"name": "land", "operator_id": "dupa", "parameters": {"lat": 45.22999954223633, "lon": 54.79999923706055, "alt": 234}}