Skip to content

Commit

Permalink
Allow recovery from corrupted items in Enum.read_many()
Browse files Browse the repository at this point in the history
  • Loading branch information
giannitedesco committed Jan 6, 2022
1 parent 2eb2026 commit 5ba290b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
40 changes: 40 additions & 0 deletions test/test_enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import unittest

from xpdt import NameSpace, StructDef, MemberDef, BaseType

class Test_RoundTrips(unittest.TestCase):
def setUp(self):
self.code = NameSpace(
structs=(
StructDef(
name='Item',
members=(
MemberDef('b', BaseType.bytes),
MemberDef('s', BaseType.utf8),
),
discriminant=0xfacebeef,
),
),
name='test',
).gen_dynamic_python()

def test_item(self):
orig = self.code.Item(b'\x00' * 4, 'Malkovich')
b = orig._enum_wrap(ts)
clone, = self.code.Test.read_many(memoryview(b))
self.assertEqual((ts, orig), clone)

def test_item(self):
bad_utf = b'\xc3\x28'
ts = 0

orig = self.code.Item(b'\xff', 'AA')

a = orig._enum_wrap(ts)
a = a[:-len(bad_utf)] + bad_utf

b = orig._enum_wrap(ts)

first, second = list(self.code.Test.read_many(memoryview(a + b)))
self.assertIsInstance(first, UnicodeDecodeError)
self.assertEqual(second, (ts, orig))
8 changes: 6 additions & 2 deletions xpdt/templates/xpdt.pyt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ from typing import (
Optional as _O,
Mapping as _M,
Dict as _Dict,
Union as _U,
)

__all__ = (
Expand Down Expand Up @@ -264,14 +265,17 @@ class $$enumclass()$$:
_unp: _F[[bytes, int], _Tup[int, ...]] = _enum_unpack_from,
_hdr_len: int = _enum_size,
_clsmap: _M[int, _Typ[$$basetype()$$]] = structs,
) -> _G[_Tup[int, $$basetype()$$], None, None]:
) -> _G[_U[_Tup[int, $$basetype()$$], Exception], None, None]:
tot_len = len(buf)
off = 0
while off < tot_len:
rec_len, discr, ts = _unp(buf, off)
off += _hdr_len
t = _clsmap[discr]
yield ts, t._frombuf(buf, off)
try:
yield ts, t._frombuf(buf, off)
except (ValueError, UnicodeDecodeError) as e:
yield e
off += rec_len

@classmethod
Expand Down

0 comments on commit 5ba290b

Please sign in to comment.