Skip to content

copt: PyObject_IsTrue error treated as truthy in IB__adapt__ #361

@jensens

Description

@jensens

A detailed analysis of _zope_interface_coptimizations.c was published at
https://gist.github.com/devdanzin/5afbad864934b165a2cc080f110aa720 by @devdanzin.
We reviewed the report with agent support and verified the findings against the
current source (zope.interface 8.2). This issue is one of several extracted from
that review.

Problem

At line 807, PyObject_IsTrue(r) returns -1 on error. The result is stored in
int implements. Line 810 tests if (implements) which is true for both 1
(truthy) and -1 (error).

A __bool__ error causes the function to return the adapted object with a
pending exception still set, violating the CPython C API contract.

Fix

implements = PyObject_IsTrue(r);
Py_DECREF(r);
if (implements < 0)
    return NULL;

Scope

1 line added.

Tests

Hard to trigger from pure Python. The PyObject_IsTrue path is only reached
when the declaration object is not a SpecificationBase (line 797 — the "security
proxy" fallback path). Triggering it requires a proxy-like object whose call
returns something with a broken __bool__. The report author also could not
reproduce this from Python.

A C-level unit test or a carefully crafted proxy mock could test this, but it
would be fragile and tightly coupled to internal dispatch logic. Recommendation:
no dedicated test. The fix is a 1-line defensive check with obvious correctness.
Code review is sufficient.

Performance impact

One integer comparison (implements < 0) on the happy path. Branch predictor
learns this is never taken within a few calls. Cost: ~0-1 CPU cycles.

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