Skip to content

Commit 3af0217

Browse files
authored
Fix decoding of map keys of certain sizes. (#59)
1 parent 148b806 commit 3af0217

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

changelog.d/59.fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix decoding of map keys of certain sizes<ISSUES_LIST>.

src/codec/packstream/v1/unpack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ impl<'a> PackStreamDecoder<'a> {
236236
fn read_string_length(&mut self) -> PyResult<usize> {
237237
let marker = self.read_byte()?;
238238
let high_nibble = marker & 0xF0;
239-
match high_nibble {
240-
TINY_STRING => Ok((marker & 0x0F) as usize),
239+
match marker {
240+
_ if high_nibble == TINY_STRING => Ok((marker & 0x0F).into()),
241241
STRING_8 => self.read_u8(),
242242
STRING_16 => self.read_u16(),
243243
STRING_32 => self.read_u32(),

tests/codec/packstream/v1/from_driver/test_packstream.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,11 +568,27 @@ def test_tiny_maps(self, assert_packable, size):
568568
data_out += bytearray([0x81, 64 + el, el])
569569
assert_packable(data_in, bytes(data_out))
570570

571+
@pytest.mark.parametrize("size", range(0x10))
572+
def test_tiny_maps_padded_key(self, assert_packable, size):
573+
data_in = {}
574+
data_out = bytearray([0xA0 + size])
575+
padding = b"1234567890abcdefghijklmnopqrstuvwxyz"
576+
for el in range(1, size + 1):
577+
data_in[padding.decode("ascii") + chr(64 + el)] = el
578+
data_out += bytearray([0xD0, 37, *padding, 64 + el, el])
579+
assert_packable(data_in, bytes(data_out))
580+
571581
def test_map_8(self, pack, assert_packable):
572582
d = {f"A{i}": 1 for i in range(40)}
573583
b = b"".join(pack(f"A{i}", 1) for i in range(40))
574584
assert_packable(d, b"\xd8\x28" + b)
575585

586+
def test_map_8_padded_key(self, pack, assert_packable):
587+
padding = "1234567890abcdefghijklmnopqrstuvwxyz"
588+
d = {f"{padding}-{i}": 1 for i in range(40)}
589+
b = b"".join(pack(f"{padding}-{i}", 1) for i in range(40))
590+
assert_packable(d, b"\xd8\x28" + b)
591+
576592
def test_map_16(self, pack, assert_packable):
577593
d = {f"A{i}": 1 for i in range(40000)}
578594
b = b"".join(pack(f"A{i}", 1) for i in range(40000))
@@ -583,6 +599,30 @@ def test_map_32(self, pack, assert_packable):
583599
b = b"".join(pack(f"A{i}", 1) for i in range(80000))
584600
assert_packable(d, b"\xda\x00\x01\x38\x80" + b)
585601

602+
def test_map_key_tiny_string(self, assert_packable):
603+
key = "A"
604+
d = {key: 1}
605+
data_out = b"\xa1\x81" + key.encode("utf-8") + b"\x01"
606+
assert_packable(d, bytes(data_out))
607+
608+
def test_map_key_string_8(self, assert_packable):
609+
key = "A" * 40
610+
d = {key: 1}
611+
data_out = b"\xa1\xd0\x28" + key.encode("utf-8") + b"\x01"
612+
assert_packable(d, data_out)
613+
614+
def test_map_key_string_16(self, assert_packable):
615+
key = "A" * 40000
616+
d = {key: 1}
617+
data_out = b"\xa1\xd1\x9c\x40" + key.encode("utf-8") + b"\x01"
618+
assert_packable(d, data_out)
619+
620+
def test_map_key_string_32(self, assert_packable):
621+
key = "A" * 80000
622+
d = {key: 1}
623+
data_out = b"\xa1\xd2\x00\x01\x38\x80" + key.encode("utf-8") + b"\x01"
624+
assert_packable(d, data_out)
625+
586626
def test_empty_dataframe_maps(self, assert_packable):
587627
df = pd.DataFrame()
588628
assert_packable(df, b"\xa0", {})

0 commit comments

Comments
 (0)