Skip to content

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

@Legoclones

Description

@Legoclones

Bug report

Bug description:

This issue is similar to Issue #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.

if slotstate:

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

if (!PyDict_Check(slotstate)) {

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.

if (slotstate != NULL) {

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions