Found in the post-#933 survey and executed against a Debug build of main (f2bafeb), with node v24.4.1 as the oracle.
new Function(P, body) (and the GeneratorFunction, AsyncFunction and AsyncGeneratorFunction constructors) parse the parameters on their own. The body is only ever parsed inside the assembled (function anonymous(P\n) {\nbody\n}). A body that closes the function early therefore passes, and whatever follows it runs when the function is constructed:
| program | node | zig-js |
|---|---|---|
var r; new Function("}); r = \"injected\"; (function(){"); r | SyntaxError | injected |
the same body through GeneratorFunction and AsyncFunction | SyntaxError | injected |
new Function("}, function(){ return \"inj\" ")() | SyntaxError | inj (the constructor returns the injected function) |
bodies }, function(){ and })(); (function(){ | SyntaxError | accepted |
CreateDynamicFunction (ECMA-262 20.2.1.1.1) requires the body text to parse on its own as a FunctionBody before the assembled source is parsed. V8 and JavaScriptCore implement the same rule by checking that the single parse yields exactly one function literal ending at the appended }.
This is both a conformance bug and an embedder-safety one: code that builds a function from an untrusted body string expects a SyntaxError, not execution.
Fix: after parsing the assembled source, require exactly one expression statement that is a function expression whose body closes at the constructor's own }, in both constructor paths.
Done: all six programs throw SyntaxError in all four constructors. Valid bodies are unchanged, including a trailing // comment and a leading HTML close comment -->. Pinned as focused cases. Debug before/after --diag over test/built-ins/Function, GeneratorFunction, AsyncFunction, AsyncGeneratorFunction and test/annexB shows 0 failures on both sides.