https://github.com/python/cpython/commit/af1be50e4cfd09a6037c31f0415ab6888d8e04fb
commit: af1be50e4cfd09a6037c31f0415ab6888d8e04fb
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: StanFromIreland <[email protected]>
date: 2026-09-25T15:58:15+01:00
summary:

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

(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 01cc654626be18..d74732d6229f00 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 00000000000000..a5adf101c9dad3
--- /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 e2c7908c9bb275..dc89f1d899e36b 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