Skip to content

gh-154848: Enforce frame boundaries in the C unpickler - #154893

Merged
serhiy-storchaka merged 3 commits into
python:mainfrom
serhiy-storchaka:pickle-frame-boundary
Jul 31, 2026
Merged

gh-154848: Enforce frame boundaries in the C unpickler#154893
serhiy-storchaka merged 3 commits into
python:mainfrom
serhiy-storchaka:pickle-frame-boundary

Conversation

@serhiy-storchaka

Copy link
Copy Markdown
Member

The C unpickler did not enforce PEP 3154 frame boundaries: an opcode or its argument could straddle a frame, and a new frame could begin before the previous one ended. Reads simply continued across the boundary.

So pickle.loads() could produce a different object than pickletools.dis() shows for the same bytes — e.g. a pickle that disassembles as a plain BINBYTES but calls builtins.print on load. The pure-Python unpickler already rejects these.

Such reads now raise UnpicklingError, matching the pure-Python implementation, with no overhead on the unframed read path.

The C unpickler did not enforce PEP 3154 frame boundaries: an opcode or its
argument could straddle a frame, and a new frame could begin before the
previous one ended.  Such reads now raise UnpicklingError, as in the pure
Python implementation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
serhiy-storchaka and others added 2 commits July 30, 2026 09:50
An opcode is a single byte and cannot straddle a frame boundary; only an
argument can.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The tests only use opcodes available in protocol 4 (FRAME being the newest),
so the PROTO header now declares protocol 4 instead of 5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@serhiy-storchaka serhiy-storchaka added the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label Jul 31, 2026
@serhiy-storchaka
serhiy-storchaka merged commit 10a8454 into python:main Jul 31, 2026
55 checks passed
@miss-islington-app

Copy link
Copy Markdown

Thanks @serhiy-storchaka for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14, 3.15.
🐍🍒⛏🤖

@serhiy-storchaka
serhiy-storchaka deleted the pickle-frame-boundary branch July 31, 2026 09:04
@miss-islington-app

Copy link
Copy Markdown

Sorry, @serhiy-storchaka, I could not cleanly backport this to 3.14 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 10a84540c2c2533e31f5f0649cc4e4afdd991ba2 3.14

@bedevere-app

bedevere-app Bot commented Jul 31, 2026

Copy link
Copy Markdown

GH-154977 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label Jul 31, 2026
@miss-islington-app

Copy link
Copy Markdown

Sorry, @serhiy-storchaka, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 10a84540c2c2533e31f5f0649cc4e4afdd991ba2 3.13

@bedevere-app

bedevere-app Bot commented Jul 31, 2026

Copy link
Copy Markdown

GH-154981 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Jul 31, 2026
@bedevere-app

bedevere-app Bot commented Jul 31, 2026

Copy link
Copy Markdown

GH-154982 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 bugs and security fixes label Jul 31, 2026
serhiy-storchaka added a commit that referenced this pull request Jul 31, 2026
) (GH-154977)

The C unpickler did not enforce PEP 3154 frame boundaries: an opcode or its
argument could straddle a frame, and a new frame could begin before the
previous one ended.  Such reads now raise UnpicklingError, as in the pure
Python implementation.
(cherry picked from commit 10a8454)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
serhiy-storchaka added a commit that referenced this pull request Jul 31, 2026
) (GH-154981)

The C unpickler did not enforce PEP 3154 frame boundaries: an argument could
straddle a frame, and a new frame could begin before the previous one ended.
Such reads now raise UnpicklingError, as in the pure Python implementation.

(cherry picked from commit 10a8454)
serhiy-storchaka added a commit that referenced this pull request Jul 31, 2026
) (GH-154982)

The C unpickler did not enforce PEP 3154 frame boundaries: an argument could
straddle a frame, and a new frame could begin before the previous one ended.
Such reads now raise UnpicklingError, as in the pure Python implementation.

(cherry picked from commit 10a8454)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant