Skip to content

gh-151763: Fix double decref in _PyPegen_raise_error_known_location()#151931

Open
manoj-marimuthu wants to merge 2 commits into
python:mainfrom
manoj-marimuthu:fix-double-decref
Open

gh-151763: Fix double decref in _PyPegen_raise_error_known_location()#151931
manoj-marimuthu wants to merge 2 commits into
python:mainfrom
manoj-marimuthu:fix-double-decref

Conversation

@manoj-marimuthu

@manoj-marimuthu manoj-marimuthu commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

The following PR addresses OOM-00019 from issue-151763.

Issue:

The _PyPegen_raise_error_known_location() in pegen_errors.c uses the Py_BuildValue function on a PyObject* called error_line with reference-stealing N format.

tmp = Py_BuildValue("(OnnNnn)", p->tok->filename, lineno, col_number, error_line, end_lineno, end_col_number);

when Py_BuildValue fails it returns NULL (ie tmp becomes NULL). when tmp == NULL, we do:

if (!tmp) {
        goto error;
    }

and goto error does:

error:
    Py_XDECREF(errstr);
    Py_XDECREF(error_line);
    return NULL;

This means that even if Py_BuildValue has decref'd error_line already, goto error repeats it which in turn trips _Py_NegativeRefcount: on debug builds.

Reproduced using:

import ast, _testcapi, faulthandler
faulthandler.enable()
src = "x y z\n"                 # generic invalid syntax -> located SyntaxError
_testcapi.set_nomemory(55, 0)   # fail every allocation from #55 onward
try:
    ast.parse(src)              # error_line built OK, then Py_BuildValue fails
                                # -> N-arg already consumed -> error: decrefs it again
finally:
    _testcapi.remove_mem_hooks()
  • In debug build (tested on windows), it gives:
D:\open source\cpython\Include\refcount.h:520: _Py_NegativeRefcount: Assertion failed: object has negative ref count
<object at 000001FC999C04F0 is freed>
Fatal Python error: _PyObject_AssertFailed: _PyObject_AssertFailed
Python runtime state: initialized
object address  : 000001FC9931C4B0
object refcount : 1
object type     : 00007FF875688D10
object type name: MemoryError
object repr     : 
lost sys.stderr

Current thread 0x00003d48 (most recent call first):
  File "D:\open source\cpython\Lib\ast.py", line 46 in parse
  File "D:\open source\cpython\PCBuild\amd64\reproducer.py", line 6 in <module>

Extension modules: _testcapi (total: 1)

Fix

we can fix this by setting error_line to NULL just after tmp's declaration so that Py_XDECREF(error_line); neglects it when Py_BuildValue() fails.

error_line = NULL;

It now raises a MemoryError correctly.

Tested on - windows

branch - 3.16.0a0

@manoj-marimuthu manoj-marimuthu changed the title Fix double decref gh-151763: Fix double decref in _PyPegen_raise_error_known_location() Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant