Skip to content

Commit ec3731c

Browse files
Fix an OOB read in the hz incremental decoder on a trailing ~
1 parent d85fa1a commit ec3731c

3 files changed

Lines changed: 12 additions & 1 deletion

File tree

Lib/test/test_multibytecodec.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,15 @@ def test_iso2022(self):
265265
self.assertRaises(UnicodeDecodeError, decoder.decode, b'', True)
266266
self.assertEqual(decoder.decode(b'B@$'), '\u4e16')
267267

268+
def test_hz_keep_buffer(self):
269+
# A trailing '~' shouldn't read past the end of the input.
270+
decoder = codecs.getincrementaldecoder('hz')()
271+
self.assertEqual(decoder.decode(b'~'), '')
272+
self.assertRaises(UnicodeDecodeError, decoder.decode, b'', True)
273+
self.assertEqual(decoder.decode(b'~'), '~')
274+
self.assertEqual(decoder.decode(b'~'), '')
275+
self.assertEqual(decoder.decode(b'\n', True), '')
276+
268277
def test_decode_unicode(self):
269278
# Trying to decode a unicode string should raise a TypeError
270279
for enc in ALL_CJKENCODINGS:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix an out-of-bounds read in the ``hz`` incremental decoder when the input
2+
ends with ``~``.

Modules/cjkcodecs/_codecs_cn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,9 @@ DECODER(hz)
414414
Py_UCS4 decoded;
415415

416416
if (c == '~') {
417+
REQUIRE_INBUF(2);
417418
unsigned char c2 = INBYTE2;
418419

419-
REQUIRE_INBUF(2);
420420
if (c2 == '~' && state->c[CN_STATE_OFFSET] == 0)
421421
OUTCHAR('~');
422422
else if (c2 == '{' && state->c[CN_STATE_OFFSET] == 0)

0 commit comments

Comments
 (0)