python / python/cpython

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

Offen
#144,411 4 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

extension-modules type-bug
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
35.9k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Vergleiche die Implementierung von load_build in Lib/pickle.py mit Modules/_pickle.c und verwende die Nutzlast b'NN\x8f\x86b.', um das abweichende Verhalten zu reproduzieren. Prüfe den verknüpften PR gh-144582 und bestätige, dass beide Implementierungen einen falsy slotstate, der kein Dictionary ist, konsistent ablehnen, wobei das relevante pickle-Verhalten durch Tests abgedeckt ist, falls der PR diese identifiziert.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.