gh-84353: Preserve non-UTF-8 filenames when appending to ZipFile - #150091
Merged
gpshead merged 4 commits intoMay 27, 2026
Conversation
- Rename bad_expected_names -> mojibake_expected_names in the append / comment tests. - The comment on newname2 was potentially misleading: it is representable in cp437 but is still stored as UTF-8 (new entries default to UTF-8 flag). - Reword the NEWS entry.
gpshead
approved these changes
May 27, 2026
gpshead
enabled auto-merge (squash)
May 27, 2026 17:28
Member
Author
|
I did not see suggestions, but all of them make sense. Thanks! |
|
Thanks @serhiy-storchaka for the PR, and @gpshead for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14, 3.15. |
|
GH-150527 is a backport of this pull request to the 3.15 branch. |
|
GH-150528 is a backport of this pull request to the 3.14 branch. |
|
GH-150529 is a backport of this pull request to the 3.13 branch. |
danny0838
added a commit
to danny0838/cpython
that referenced
this pull request
Jul 2, 2026
Fix a regression introduced by pythongh-84353/pythongh-150091 where the EFS flag was dropped or omitted when a file with an ASCII filename and a UTF-8 comment was written to an archive. This affected both newly added files and existing files rewritten to the central directory in append mode, causing an unexpected metadata change and leading to comment mis-decoding. Introduce an internal `_metadata_encoding` attribute for `ZipInfo` to ensure that files read from an archive preserve their original encoding and EFS flags, while newly added files now properly enforce EFS if they contain a non-ASCII filename or comment.
danny0838
added a commit
to danny0838/cpython
that referenced
this pull request
Jul 2, 2026
Fix a regression introduced by pythongh-84353/pythongh-150091 where the EFS flag was dropped or omitted when a file with an ASCII filename and a UTF-8 comment was written to an archive. This affected both newly added files and existing files rewritten to the central directory in append mode, causing an unexpected metadata change and leading to comment mis-decoding. Introduce an internal `_metadata_encoding` attribute for `ZipInfo` to ensure that files read from an archive preserve their original encoding and EFS flags, while newly added files now properly enforce EFS if they contain a non-ASCII filename or comment.
danny0838
added a commit
to danny0838/cpython
that referenced
this pull request
Jul 2, 2026
Fix a regression introduced by pythongh-84353/pythongh-150091 where the EFS flag was dropped or omitted when a file with an ASCII filename and a UTF-8 comment was written to an archive. This affected both newly added files and existing files rewritten to the central directory in append mode, causing an unexpected metadata change and leading to comment mis-decoding. Introduce an internal `_metadata_encoding` attribute for `ZipInfo` to ensure that files read from an archive preserve their original encoding and EFS flags, while newly added files now properly enforce EFS if they contain a non-ASCII filename or comment.
pR0Ps
added a commit
to pR0Ps/zipstream-ng
that referenced
this pull request
Aug 20, 2026
python/cpython#150091 changed the default non-utf8 encoding from 'ascii' to 'cp437' for encoding zip filenames. This means that characters that could be encoded in cp437 but not ascii would be encoded in the zip data using cp437 vs. previously they woud've used utf-8. Note that non-ascii characters that are valid cp437 characters will always take up a single byte when encoded as cp437, but multiple when encoded using utf-8. Because `len(zipstream)` assumes that filenames are encoded using only ascii or utf-8, this resulted in the calculated length being off by (at least) 1 byte for every cp437, non-ascii character in all the filenames. The fix in this commit is to override `ZipInfo._encodeFilenameFlags` to revert Python's change and force filenames to only use ascii/utf-8. The change was made to support modifying existing zips with cp437-encoded filenames which isn't relevant to this project. And while technically cp437 is the standard encoding for zipfile names, using the more strict ascii subset is less likely to be misinterpreted by unarchivers since they won't have to guess at what extended ascii encoding was used - it'll always be strict ascii or utf-8.
pR0Ps
added a commit
to pR0Ps/zipstream-ng
that referenced
this pull request
Aug 20, 2026
python/cpython#150091 changed the default non-utf8 encoding from 'ascii' to 'cp437' for encoding zip filenames. This means that characters that could be encoded in cp437 but not ascii would be encoded in the zip data using cp437 vs. previously they woud've used utf-8. Note that non-ascii characters that are valid cp437 characters will always take up a single byte when encoded as cp437, but multiple when encoded using utf-8. Because `len(zipstream)` assumes that filenames are encoded using only ascii or utf-8, this resulted in the calculated length being off by (at least) 1 byte for every cp437, non-ascii character in all the filenames. The fix in this commit is to override `ZipInfo._encodeFilenameFlags` to revert Python's change and force filenames to only use ascii/utf-8. The change was made to support modifying existing zips with cp437-encoded filenames which isn't relevant to this project. And while technically cp437 is the standard encoding for zipfile names, using the more strict ascii subset is less likely to be misinterpreted by unarchivers since they won't have to guess at what extended ascii encoding was used - it'll always be strict ascii or utf-8.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.