From bd9e77403061f891151b433b21d9d0002e1d41b1 Mon Sep 17 00:00:00 2001 From: "Enzo Persillet (Tutez)" Date: Sat, 3 Oct 2026 00:40:06 +0200 Subject: [PATCH 1/2] Report a cppia new with nothing to construct as a link failure. NewExpr::link left a NEW whose type was neither an array, a host class with a constructor, nor a script class, and both paths then dereferenced the null cppiaClass: runObject when the line ran, and genCode while the JIT compiled the module. It now reports "Could not link new" and throws "Bad link", as the other link failures do. Co-Authored-By: Claude Opus 5.5 --- src/hx/cppia/Cppia.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/hx/cppia/Cppia.cpp b/src/hx/cppia/Cppia.cpp index ba68a29fa..e6e164a2a 100644 --- a/src/hx/cppia/Cppia.cpp +++ b/src/hx/cppia/Cppia.cpp @@ -1507,6 +1507,13 @@ struct NewExpr : public CppiaDynamicExpr if (!type->cppiaClass && type->haxeClass.mPtr) constructor = type->haxeClass.mPtr->mConstructArgs; + // Nothing to construct: runObject and genCode would dereference the null cppiaClass. + if (!type->arrayType && !constructor && !type->cppiaClass) + { + CPPIALOG("Could not link new %s\n", type->name.c_str()); + throw "Bad link"; + } + LinkExpressions(args,inModule); return this; } From 7d2d8cc4428550cbf543569362ecd936f138ef2f Mon Sep 17 00:00:00 2001 From: "Enzo Persillet (Tutez)" Date: Sat, 3 Oct 2026 16:41:33 +0200 Subject: [PATCH 2/2] Test a cppia new of a class the host does not have. ClientUnlinked constructs an extern class, which the cppia module only names. Loading it must fail to link: before the fix, the JIT segfaulted while compiling the module, and without the JIT the load succeeded and left a null class to construct. Co-Authored-By: Claude Opus 5.5 --- test/cppia/ClientUnlinked.hx | 13 +++++++++++++ test/cppia/cases/TestCommon.hx | 6 ++++++ test/cppia/compile-client.hxml | 7 ++++++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/cppia/ClientUnlinked.hx diff --git a/test/cppia/ClientUnlinked.hx b/test/cppia/ClientUnlinked.hx new file mode 100644 index 000000000..c48769c07 --- /dev/null +++ b/test/cppia/ClientUnlinked.hx @@ -0,0 +1,13 @@ +// The host does not have this class: a module constructing it must fail to link. +extern class Unlinked +{ + public function new(); +} + +class ClientUnlinked +{ + public static function main() + { + new Unlinked(); + } +} diff --git a/test/cppia/cases/TestCommon.hx b/test/cppia/cases/TestCommon.hx index eaacb5a76..fdcb86d2f 100644 --- a/test/cppia/cases/TestCommon.hx +++ b/test/cppia/cases/TestCommon.hx @@ -59,6 +59,12 @@ class TestCommon extends Test { Assert.equals(2, Common.callbackSet, 'Bad cppia closure'); } + function testNewOfUnlinkedClass() { + final source = sys.io.File.getBytes('bin/unlinked.cppia'); + + Assert.raises(() -> cpp.cppia.Module.fromData(source.getData()), String, 'Linked a new of a class the host does not have'); + } + @:depends(testStatus) function testInterfaceCalling() { final obj : IFoo = Type.createInstance(Type.resolveClass('ClientFoo'), []); diff --git a/test/cppia/compile-client.hxml b/test/cppia/compile-client.hxml index 4c9c3e0c5..854e92b93 100644 --- a/test/cppia/compile-client.hxml +++ b/test/cppia/compile-client.hxml @@ -1,3 +1,8 @@ -m Client -D dll_import=host_classes.info ---cppia bin/client.cppia \ No newline at end of file +--cppia bin/client.cppia + +--next + +-m ClientUnlinked +--cppia bin/unlinked.cppia