Skip to content

load_obj_dict unchecked PyDict_New + fontext copy-paste bug + unchecked PyModule_AddObject for UserKeyError #603

Description

@devdanzin

Three smaller bugs across different files:

1. load_obj_dict unchecked PyDict_New corrupts dict pointer (signaling.cpp:98)

When forcecreate is true and *dict is NULL, PyDict_New() is called but its return value is not checked. On OOM, NULL is stored into *dict and the function returns true (success). The caller's object now has a corrupted __dict__ pointer.

Fix:

if( forcecreate && !*dict )
{
    *dict = PyDict_New();
    if( !*dict )
        return false;
}

2. Copy-paste bug in fontext.cpp:341!PyFontCaps instead of !PyFontStretch

After creating PyFontStretch, the code checks PyFontCaps (the previous variable):

cppy::ptr PyFontStretch( new_enum_class( "FontStretch" ) );
if( !PyFontCaps )   // BUG: should be !PyFontStretch
{
    return -1;
}

If new_enum_class("FontStretch") fails, NULL propagates to later use. Currently latent because creation succeeds, but a real bug if the allocation ever fails.

Also, the slot array is named Nonlocals_Type_slots (copy-paste from dynamicscope.cpp) instead of Font_Type_slots (line 239).

3. Unchecked PyModule_AddObject for UserKeyError (dynamicscope.cpp:927)

The only PyModule_AddObject call in the codebase that doesn't follow the cppy::ptr + check + release() pattern. Return value ignored; on failure the error is silently swallowed.

Fix: use PyModule_AddObjectRef (available since 3.10):

if( PyModule_AddObjectRef( mod, "UserKeyError", UserKeyError ) < 0 )
    return -1;

Found by cext-review-toolkit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions