From f742c5e2c17574df065d7e5d02899124f59041bb Mon Sep 17 00:00:00 2001 From: Felix Berlakovich Date: Tue, 5 May 2026 15:25:33 +0200 Subject: [PATCH 1/5] Handle native float subtype allocation failure --- .../src/floatobject.c | 3 +-- .../src/tests/cpyext/test_float.py | 20 ++++++++++++++++++- .../builtins/objects/cext/capi/CExtNodes.java | 5 +++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/graalpython/com.oracle.graal.python.cext/src/floatobject.c b/graalpython/com.oracle.graal.python.cext/src/floatobject.c index a620a08f61..48c39b8c81 100644 --- a/graalpython/com.oracle.graal.python.cext/src/floatobject.c +++ b/graalpython/com.oracle.graal.python.cext/src/floatobject.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, 2025, Oracle and/or its affiliates. +/* Copyright (c) 2018, 2026, Oracle and/or its affiliates. * Copyright (C) 1996-2017 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -2689,7 +2689,6 @@ GraalPyPrivate_Float_SubtypeNew(PyTypeObject *type, double x) { PyObject* newobj = type->tp_alloc(type, 0); if (newobj == NULL) { - Py_DECREF(newobj); return NULL; } ((PyFloatObject *)newobj)->ob_fval = x; diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py index 6f4b3cb978..6af96bee8a 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py @@ -1,4 +1,4 @@ -# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -245,6 +245,24 @@ class ManagedSubclass(NativeFloatSubclass): f = ManagedSubclass(1.0) assert is_native_object(f) + def test_alloc_failure(self): + FailingAllocFloatSubclass = CPyExtType( + 'FailingAllocFloatSubclass', + r''' + static PyObject* fail_alloc(PyTypeObject *type, Py_ssize_t nitems) { + PyErr_NoMemory(); + return NULL; + } + ''', + struct_base='PyFloatObject base;', + tp_base='&PyFloat_Type', + tp_new='0', + tp_alloc='fail_alloc', + tp_free='0', + ) + with self.assertRaises(MemoryError): + FailingAllocFloatSubclass(1.0) + def test_methods(self): f = NativeFloatSubclass(1.1) zero = NativeFloatSubclass(0.0) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java index 70bce259a9..05f82603aa 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java @@ -205,12 +205,13 @@ public abstract static class FloatSubtypeNew extends Node { static Object doGeneric(Object object, double arg, @Bind Node inliningTarget, @Cached PythonToNativeNode toNativeNode, - @Cached NativeToPythonTransferNode toJavaNode) { + @Cached NativeToPythonTransferNode toJavaNode, + @Cached PyObjectCheckFunctionResultNode checkFunctionResultNode) { assert TypeNodes.NeedsNativeAllocationNode.executeUncached(object); NativeFunctionPointer callable = CApiContext.getNativeSymbol(inliningTarget, NativeCAPISymbol.FUN_FLOAT_SUBTYPE_NEW); try { long result = ExternalFunctionInvoker.invokeFLOAT_SUBTYPE_NEW(callable.getAddress(), toNativeNode.executeLong(object), arg); - return toJavaNode.execute(result); + return checkFunctionResultNode.execute(PythonContext.get(inliningTarget), NativeCAPISymbol.FUN_FLOAT_SUBTYPE_NEW.getTsName(), toJavaNode.execute(result)); } catch (Throwable e) { throw CompilerDirectives.shouldNotReachHere(e); } From 8542a11ab32fe4aa2d87bbb40942478a90913814 Mon Sep 17 00:00:00 2001 From: Felix Berlakovich Date: Tue, 5 May 2026 15:25:33 +0200 Subject: [PATCH 2/5] Document Jira security report description guidance --- AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AGENTS.md b/AGENTS.md index 15732ee8f5..67e12592a2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -84,5 +84,6 @@ It consists of: Java (Truffle) + C (CPython C-API compatibility) + Python stdlib We use Jira and Bitbucket, and each PR should reference a Jira ticket with the form [GR-XXXX] where XXXX is the ticket number. When asked to open pull requests, agents should ask for the Jira ticket number. When asked to create a ticket, the `gdev-cli jira` tool can be used to create a ticket for the "Python" component. +When creating Jira tickets from BugDB or security reports, describe the issue, affected behavior, and available reproduction evidence; do not include remediation or fix guidance unless explicitly requested. When asked to create, run gates on, or check on the builds previously run on a pull request, use the `gdev-cli bitbucket` tool. When asked to add default reviewers to a graalpython PR, that currently means tim.felgentreff@oracle.com, michael.simacek@oracle.com, florian.angerer@oracle.com and stepan.sindelar@oracle.com. From c8eeb67814c25b775d37f3bafe4728322cedd920 Mon Sep 17 00:00:00 2001 From: Felix Berlakovich Date: Tue, 5 May 2026 15:48:29 +0200 Subject: [PATCH 3/5] Remove project-local Jira guidance --- AGENTS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 67e12592a2..15732ee8f5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -84,6 +84,5 @@ It consists of: Java (Truffle) + C (CPython C-API compatibility) + Python stdlib We use Jira and Bitbucket, and each PR should reference a Jira ticket with the form [GR-XXXX] where XXXX is the ticket number. When asked to open pull requests, agents should ask for the Jira ticket number. When asked to create a ticket, the `gdev-cli jira` tool can be used to create a ticket for the "Python" component. -When creating Jira tickets from BugDB or security reports, describe the issue, affected behavior, and available reproduction evidence; do not include remediation or fix guidance unless explicitly requested. When asked to create, run gates on, or check on the builds previously run on a pull request, use the `gdev-cli bitbucket` tool. When asked to add default reviewers to a graalpython PR, that currently means tim.felgentreff@oracle.com, michael.simacek@oracle.com, florian.angerer@oracle.com and stepan.sindelar@oracle.com. From 4a648a5fb4b5bd102db0533f24677236d4404adb Mon Sep 17 00:00:00 2001 From: Felix Berlakovich Date: Tue, 5 May 2026 15:53:39 +0200 Subject: [PATCH 4/5] Describe float subtype allocation failure test --- .../com.oracle.graal.python.test/src/tests/cpyext/test_float.py | 1 + 1 file changed, 1 insertion(+) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py index 6af96bee8a..9cfa28cb31 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_float.py @@ -246,6 +246,7 @@ class ManagedSubclass(NativeFloatSubclass): assert is_native_object(f) def test_alloc_failure(self): + """A native float subtype must propagate tp_alloc failure instead of crashing on NULL.""" FailingAllocFloatSubclass = CPyExtType( 'FailingAllocFloatSubclass', r''' From 124ec4d6dd296d697359ea934c420cf4451fd385 Mon Sep 17 00:00:00 2001 From: Felix Berlakovich Date: Wed, 6 May 2026 13:46:45 +0200 Subject: [PATCH 5/5] Propagate float subtype allocation failure --- .../graal/python/builtins/objects/cext/capi/CExtNodes.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java index 05f82603aa..995a9ce131 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java @@ -209,12 +209,14 @@ static Object doGeneric(Object object, double arg, @Cached PyObjectCheckFunctionResultNode checkFunctionResultNode) { assert TypeNodes.NeedsNativeAllocationNode.executeUncached(object); NativeFunctionPointer callable = CApiContext.getNativeSymbol(inliningTarget, NativeCAPISymbol.FUN_FLOAT_SUBTYPE_NEW); + long result; try { - long result = ExternalFunctionInvoker.invokeFLOAT_SUBTYPE_NEW(callable.getAddress(), toNativeNode.executeLong(object), arg); - return checkFunctionResultNode.execute(PythonContext.get(inliningTarget), NativeCAPISymbol.FUN_FLOAT_SUBTYPE_NEW.getTsName(), toJavaNode.execute(result)); + result = ExternalFunctionInvoker.invokeFLOAT_SUBTYPE_NEW(callable.getAddress(), toNativeNode.executeLong(object), arg); } catch (Throwable e) { throw CompilerDirectives.shouldNotReachHere(e); } + return checkFunctionResultNode.execute(PythonContext.get(inliningTarget), NativeCAPISymbol.FUN_FLOAT_SUBTYPE_NEW.getTsName(), + toJavaNode.execute(result)); } }