Skip to content

Commit e38d18d

Browse files
authored
Graceful handling of PCAPNG option comment UTF-8 decoding errors (#631)
* Add graceful handling of PCAPNG option comment UTF-8 decoding errors * Add Schwaggot (tom.ryan@posteo.de) to authors
1 parent 23dfff7 commit e38d18d

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

docs/authors.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,7 @@ Dug Song \<<dugsong@monkey.org>\>
7373
- crocogorical \<<crocogorical@gmail.com>\>
7474
Extend test coverage
7575

76+
- Schwaggot \<<tom.ryan@posteo.de>\>
77+
pcapng module, support for Packet Block and handling of UTF-8 option comments
78+
7679
If you want to contribute to dpkt, see `contributing`.

dpkt/pcapng.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,13 @@ def unpack(self, buf):
190190

191191
# decode comment
192192
if self.code == PCAPNG_OPT_COMMENT:
193-
self.text = self.data.decode('utf-8')
193+
try:
194+
self.text = self.data.decode('utf-8')
195+
except UnicodeDecodeError as ude:
196+
if b'\x00' in self.data:
197+
self.text = self.data[:self.data.index(b'\x00')].decode('ascii')
198+
else:
199+
raise ude
194200

195201
def __bytes__(self):
196202
# encode comment
@@ -759,6 +765,49 @@ def test_epb():
759765
assert len(epb) == len(buf)
760766

761767

768+
def test_epb_ascii_comment_option():
769+
"""Test EPB with an ascii comment option"""
770+
buf = (
771+
b'\x06\x00\x00\x00\x7c\x00\x00\x00\x01\x00\x00\x00\xff\xff\xff\xff\x79\xd2\xdf\xe1\x44\x00'
772+
b'\x00\x00\x44\x00\x00\x00\x00\x00\x00\x01\x00\x06\x00\x0b\xdb\x43\xe7\x4b\xf6\x7f\x08\x00'
773+
b'\x45\x00\x00\x34\x2b\x1f\x40\x00\x40\x06\x15\x63\x82\xd9\xfa\x81\x82\xd9\xfa\x0d\x17\x70'
774+
b'\xec\x3e\x02\xba\x94\x38\x81\x52\x4a\x39\x80\x10\xbb\x5d\x53\x0d\x00\x00\x01\x01\x08\x0a'
775+
b'\x03\xf9\xc7\xbf\x04\x02\x38\x28\x01\x00\x0f\x00\x50\x61\x63\x6b\x65\x74\x20\x23\x31\x00'
776+
b'\x78\x4d\x39\x87\x0c\x00\x00\x00\x00\x00\x7c\x00\x00\x00')
777+
778+
# block unpacking
779+
epb = EnhancedPacketBlockLE(buf)
780+
781+
# options unpacking
782+
assert len(epb.opts) == 2
783+
assert epb.opts[0].code == PCAPNG_OPT_COMMENT
784+
assert epb.opts[0].text == 'Packet #1'
785+
786+
assert epb.opts[1].code == PCAPNG_OPT_ENDOFOPT
787+
assert epb.opts[1].len == 0
788+
789+
# option packing
790+
assert bytes(epb.opts[0]) == b'\x01\x00\x09\x00\x50\x61\x63\x6b\x65\x74\x20\x23\x31\x00\x00\x00'
791+
assert len(epb.opts[0]) == 16
792+
assert bytes(epb.opts[1]) == b'\x00\x00\x00\x00'
793+
794+
795+
def test_epb_invalid_utf8_comment_option():
796+
"""Test EPB with an invalid (non UTF-8, non-zero terminated ascii) comment option"""
797+
buf = (
798+
b'\x06\x00\x00\x00\x7c\x00\x00\x00\x01\x00\x00\x00\xff\xff\xff\xff\x79\xd2\xdf\xe1\x44\x00'
799+
b'\x00\x00\x44\x00\x00\x00\x00\x00\x00\x01\x00\x06\x00\x0b\xdb\x43\xe7\x4b\xf6\x7f\x08\x00'
800+
b'\x45\x00\x00\x34\x2b\x1f\x40\x00\x40\x06\x15\x63\x82\xd9\xfa\x81\x82\xd9\xfa\x0d\x17\x70'
801+
b'\xec\x3e\x02\xba\x94\x38\x81\x52\x4a\x39\x80\x10\xbb\x5d\x53\x0d\x00\x00\x01\x01\x08\x0a'
802+
b'\x03\xf9\xc7\xbf\x04\x02\x38\x28\x01\x00\x0f\x00\x50\x61\x63\x6b\x65\x74\x20\x23\x31\x20'
803+
b'\x78\x4d\x39\x87\x0c\x00\x00\x00\x00\x00\x7c\x00\x00\x00')
804+
805+
try:
806+
EnhancedPacketBlockLE(buf)
807+
except Exception as e:
808+
assert isinstance(e, UnicodeDecodeError)
809+
810+
762811
def test_simple_write_read():
763812
"""Test writing a basic pcapng and then reading it"""
764813
fobj = BytesIO()

0 commit comments

Comments
 (0)