python / python/cpython

Pickle `load_build` function checks if `slotstate` is False, not a dict

オープン
#144,411 コメント 4 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

extension-modules type-bug
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

Bug report

Bug description:

This issue is similar to Issue https://github.com/python/cpython/issues/128965. Inside of the load_build() function, Python pickle assumes that slotstate is a dictionary while C _pickle explicitly checks to ensure it's a dictionary. The behavior of these two implementations diverge when slotstate is falsey but not a dictionary.

payload:      b'NN\x8f\x86b.'

pickle:       None
_pickle.c:    FAILURE slot state is not a dictionary
pickletools:
    0: N    NONE
    1: N    NONE
    2: \x8f EMPTY_SET
    3: \x86 TUPLE2
    4: b    BUILD
    5: .    STOP
highest protocol among opcodes = 4

In this case, opcode 2 (EMPTY_SET) is slotstate. When running in pickle.py, this is falsey and thus the code inside setting attributes will not be run, causing the pickle to continue deserializing without any errors.

https://github.com/python/cpython/blob/29acc08c8dad664cd5713cb392e5beba65724c10/Lib/pickle.py#L1868

When running in _pickle.c, this value is not a dictionary, causing an error to be thrown.

https://github.com/python/cpython/blob/29acc08c8dad664cd5713cb392e5beba65724c10/Modules/_pickle.c#L6903

I guess also in general I'm not understanding what the if slotstate in pickle.py is meant to do anyway. If it's supposed to check if slotstate == None, then the C _pickle module doesn't do that correctly. It checks if slotstate is NULL, which is not the same as PyNone.

https://github.com/python/cpython/blob/29acc08c8dad664cd5713cb392e5beba65724c10/Modules/_pickle.c#L6899

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs
  • gh-144582

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

Lib/pickle.py の load_build の実装を Modules/_pickle.c と比較し、payload b'NN\x8f\x86b.' を使って挙動の相違を再現してください。リンクされた PR gh-144582 を確認し、両方の実装が dictionary ではない falsy な slotstate を一貫して拒否することを確認してください。PR で関連する pickle の挙動を対象とするテストが特定されている場合は、そのテストでカバーされていることも確認してください。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。