Skip to content

gh-154863: Fix iconv encoding of ISO-2022-CN-EXT returning empty bytes - #154899

Merged
serhiy-storchaka merged 2 commits into
python:mainfrom
fedonman:fix-iconv-encode-flush-count
Jul 31, 2026
Merged

gh-154863: Fix iconv encoding of ISO-2022-CN-EXT returning empty bytes#154899
serhiy-storchaka merged 2 commits into
python:mainfrom
fedonman:fix-iconv-encode-flush-count

Conversation

@fedonman

@fedonman fedonman commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Encoding ends with an iconv() call on a NULL input to flush the pending shift sequence.
That call's return value counts nonreversible conversions, and glibc makes it 1 for
ISO-2022-CN-EXT. The loop read any positive count as "iconv substituted an unencodable
character" and restarted one code point at a time, but flushing was still set, so the
retry fed no input, returned 0 and broke out with the output buffer already reset to
empty.

Checking flushing before the count fixes it. The retry path cannot be reached while
flushing, so nothing else changes.

>>> 'ABC中DEF'.encode('iso-2022-cn-ext')
b'ABC\x1b$)A\x0eVP\x0fDEF\x0f'

I compared the codec against raw iconv for all 1180 encodings iconv -l lists here.
ISO-2022-CN-EXT and its alias were the only two that disagreed, and none do now. The test
also covers ISO-2022-CN and ISO-2022-JP, where the flush count is 0, so those pass either
way and act as controls. It fails without the change.

The (b'', 1) consumed count in the report is not a second bug. iconv_encode() always
consumes the whole string, so the length is correct.

The iconv codecs are new in 3.16, so there is no NEWS entry.

…y bytes

The flush that emits the pending shift sequence can report a nonreversible
conversion, which the loop mistook for a substituted character. It then
retried while still flushing, converted nothing and returned the empty
output buffer.
macOS substitutes '?' for the Chinese character in ISO-2022-CN instead of
encoding it, so check only that the surrounding ASCII survives, which is
what the fix is about.

@serhiy-storchaka serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 👍

@serhiy-storchaka
serhiy-storchaka enabled auto-merge (squash) July 31, 2026 10:42
@serhiy-storchaka
serhiy-storchaka merged commit d2ace0c into python:main Jul 31, 2026
96 of 98 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants