Skip to content

gh-154490: Only keep permission bits of the mode argument in ZipFile.mkdir()#154509

Open
DevoidSloth wants to merge 1 commit into
python:mainfrom
DevoidSloth:gh-154490-zipfile-mkdir-mode
Open

gh-154490: Only keep permission bits of the mode argument in ZipFile.mkdir()#154509
DevoidSloth wants to merge 1 commit into
python:mainfrom
DevoidSloth:gh-154490-zipfile-mkdir-mode

Conversation

@DevoidSloth

@DevoidSloth DevoidSloth commented Jul 22, 2026

Copy link
Copy Markdown

ZipFile.mkdir() combines the caller-provided mode into the entry's external attributes without clearing the file type bits, so those bits can mark the created entry as something other than a directory:

>>> import io, stat, zipfile
>>> with zipfile.ZipFile(io.BytesIO(), 'w') as zh:
...     zh.mkdir('foo/', 0o107777)
...     print(oct(stat.S_IFMT(zh.getinfo('foo/').external_attr >> 16)))
...
0o140000   # socket, not a directory

This PR sanitizes mode to its permission bits before combining it with S_IFDIR, matching what stat.S_IMODE() does, as suggested in the issue:

zinfo.external_attr = (0o40000 | (mode & 0o7777)) << 16

It also spells the default mode as 0o777 instead of 511 in the signature and documentation, for consistency with os.mkdir() (same value, clearer intent).

Included:

  • Regression assertions in test_mkdir covering S_IFREG and S_IFLNK type bits in mode, plus an extractall() round-trip.
  • Documentation update for ZipFile.mkdir() with a versionchanged note.
  • NEWS entry.

…pFile.mkdir()

The file type bits of a caller-provided mode were previously mixed into
the entry's external attributes, so a mode such as 0o107777 could mark
the created entry as a socket instead of a directory.  Sanitize the mode
with & 0o7777, matching what stat.S_IMODE does, before combining it with
S_IFDIR.  Also spell the default mode as 0o777 instead of 511 in the
signature and documentation, for consistency with os.mkdir().
@python-cla-bot

python-cla-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #33715264 | 📁 Comparing ed08556 against main (a2a8466)

  🔍 Preview build  

2 files changed
± library/zipfile.html
± whatsnew/changelog.html

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