Skip to content

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

Open
fedonman wants to merge 2 commits into
python:mainfrom
fedonman:fix-iconv-encode-flush-count
Open

gh-154863: Fix iconv encoding of ISO-2022-CN-EXT returning empty bytes#154899
fedonman wants to merge 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.
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.

1 participant