diff --git a/Lib/test/test_codecencodings_iso2022.py b/Lib/test/test_codecencodings_iso2022.py index 027dbecc6134df..4515997dfa02a2 100644 --- a/Lib/test/test_codecencodings_iso2022.py +++ b/Lib/test/test_codecencodings_iso2022.py @@ -15,6 +15,10 @@ class Test_ISO2022_JP(multibytecodec_support.TestBase, unittest.TestCase): tstring = multibytecodec_support.load_teststring('iso2022_jp') codectests = COMMON_CODEC_TESTS + ( (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), + # there is no G1 in this encoding + (b'ab\x1B$)Bdef', 'strict', None), + (b'ab\x1B)Jdef', 'strict', None), + (b'ab\x1B)Bdef', 'strict', None), ) class Test_ISO2022_JP2(multibytecodec_support.TestBase, unittest.TestCase): @@ -22,6 +26,14 @@ class Test_ISO2022_JP2(multibytecodec_support.TestBase, unittest.TestCase): tstring = multibytecodec_support.load_teststring('iso2022_jp') codectests = COMMON_CODEC_TESTS + ( (b'ab\x1BNdef', 'replace', 'abdef'), + # a charset can only be designated to its own plane + (b'\x1B.A\x1BNi', 'strict', '\xe9'), + (b'\x1B$(C\x30\x21\x1B(B', 'strict', '\uac00'), + (b'ab\x1B(Adef', 'strict', None), + (b'ab\x1B(Fdef', 'strict', None), + (b'ab\x1B.J\x1BNdef', 'strict', None), + (b'ab\x1B.Bdef', 'strict', None), + (b'ab\x1B$)Cdef', 'strict', None), ) class Test_ISO2022_JP3(multibytecodec_support.TestBase, unittest.TestCase): @@ -75,6 +87,12 @@ class Test_ISO2022_KR(multibytecodec_support.TestBase, unittest.TestCase): tstring = multibytecodec_support.load_teststring('iso2022_kr') codectests = COMMON_CODEC_TESTS + ( (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), + # KS X 1001 can only be designated to G1 + (b'\x1B$)C\x0E\x30\x21\x0Fdef', 'strict', '\uac00def'), + (b'ab\x1B$(Cdefg', 'strict', None), + (b'ab\x1B$Cdefg', 'strict', None), + (b'ab\x1B)Bdefg', 'strict', None), + (b'ab\x1B$(Cdefg', 'replace', 'ab\ufffddefg'), ) # iso2022_kr.txt cannot be used to test "chunk coding": the escape diff --git a/Misc/NEWS.d/next/Library/2026-10-22-00-30-04.gh-issue-160187.9dcj2B.rst b/Misc/NEWS.d/next/Library/2026-10-22-00-30-04.gh-issue-160187.9dcj2B.rst new file mode 100644 index 00000000000000..74ee6c1fa7bbb9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-22-00-30-04.gh-issue-160187.9dcj2B.rst @@ -0,0 +1,4 @@ +Fix the ISO-2022 decoders (``iso2022_jp``, ``iso2022_kr`` and related) +accepting escape sequences that designate a character set to the wrong code +element (G0, G1 or G2). Such sequences now raise :exc:`UnicodeDecodeError` +instead of producing wrong text or :exc:`RuntimeError`. diff --git a/Modules/cjkcodecs/_codecs_iso2022.c b/Modules/cjkcodecs/_codecs_iso2022.c index 662c2e1188e817..0a017cfc445fc9 100644 --- a/Modules/cjkcodecs/_codecs_iso2022.c +++ b/Modules/cjkcodecs/_codecs_iso2022.c @@ -382,17 +382,22 @@ iso2022processesc(const MultibyteCodec *codec, MultibyteCodec_State *state, return esclen; } - /* raise error when the charset is not designated for this encoding */ + /* raise error when the charset is not designated to this plane for + * this encoding (ASCII is only ever designated to G0) */ if (charset != CHARSET_ASCII) { const struct iso2022_designation *dsg; for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { - if (dsg->mark == charset) + if (dsg->mark == charset && dsg->plane == designation) { break; + } } if (!dsg->mark) return esclen; } + else if (designation != 0) { + return esclen; + } STATE_SETG(designation, charset); *inleft -= esclen;