https://github.com/python/cpython/commit/6907605aae5425494a3484d9221ca8c24000b9de
commit: 6907605aae5425494a3484d9221ca8c24000b9de
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: StanFromIreland <[email protected]>
date: 2026-09-28T12:25:48Z
summary:

[3.14] gh-157325: Fix an OOB read in the `hz` incremental decoder on a trailing 
`~` (gh-157333) (#158162)

(cherry picked from commit c04387348eb8223977e46f4972c08833c11c6617)

Co-authored-by: Stan Ulbrych <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-09-11-16-50-11.gh-issue-157325.hzTild.rst
M Lib/test/test_multibytecodec.py
M Modules/cjkcodecs/_codecs_cn.c

diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py
index 6b032fc8604eefd..0cd822fef874003 100644
--- a/Lib/test/test_multibytecodec.py
+++ b/Lib/test/test_multibytecodec.py
@@ -265,6 +265,15 @@ def test_iso2022(self):
         self.assertRaises(UnicodeDecodeError, decoder.decode, b'', True)
         self.assertEqual(decoder.decode(b'B@$'), '\u4e16')
 
+    def test_hz_keep_buffer(self):
+        # A trailing '~' shouldn't read past the end of the input.
+        decoder = codecs.getincrementaldecoder('hz')()
+        self.assertEqual(decoder.decode(b'~'), '')
+        self.assertRaises(UnicodeDecodeError, decoder.decode, b'', True)
+        self.assertEqual(decoder.decode(b'~'), '~')
+        self.assertEqual(decoder.decode(b'~'), '')
+        self.assertEqual(decoder.decode(b'\n', True), '')
+
     def test_decode_unicode(self):
         # Trying to decode a unicode string should raise a TypeError
         for enc in ALL_CJKENCODINGS:
diff --git 
a/Misc/NEWS.d/next/Library/2026-09-11-16-50-11.gh-issue-157325.hzTild.rst 
b/Misc/NEWS.d/next/Library/2026-09-11-16-50-11.gh-issue-157325.hzTild.rst
new file mode 100644
index 000000000000000..a5adf101c9dad3c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-09-11-16-50-11.gh-issue-157325.hzTild.rst
@@ -0,0 +1,2 @@
+Fix an out-of-bounds read in the ``hz`` incremental decoder when the input
+ends with ``~``.
diff --git a/Modules/cjkcodecs/_codecs_cn.c b/Modules/cjkcodecs/_codecs_cn.c
index e2c7908c9bb2753..dc89f1d899e36be 100644
--- a/Modules/cjkcodecs/_codecs_cn.c
+++ b/Modules/cjkcodecs/_codecs_cn.c
@@ -414,9 +414,9 @@ DECODER(hz)
         Py_UCS4 decoded;
 
         if (c == '~') {
+            REQUIRE_INBUF(2);
             unsigned char c2 = INBYTE2;
 
-            REQUIRE_INBUF(2);
             if (c2 == '~' && state->c[CN_STATE_OFFSET] == 0)
                 OUTCHAR('~');
             else if (c2 == '{' && state->c[CN_STATE_OFFSET] == 0)

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to