@@ -198,6 +198,21 @@ class Benchmark {
198198 }
199199
200200 _run ( ) {
201+ // A forked child is told to run the benchmark function directly, rather
202+ // than build its own queue and fork again, through the
203+ // NODE_RUN_BENCHMARK_FN environment variable. A child always inherits
204+ // this.flags in its execArgv, so reaching _run() with those flags already
205+ // applied means the variable did not survive to the child and every
206+ // generation would keep forking. Fail loudly instead of forking forever.
207+ if ( process . send &&
208+ this . flags . length > 0 &&
209+ this . flags . every ( ( flag ) => process . execArgv . includes ( flag ) ) ) {
210+ throw new Error (
211+ 'Benchmark child process was started with the benchmark flags but ' +
212+ 'without NODE_RUN_BENCHMARK_FN, refusing to fork again. Something ' +
213+ 'removed the variable from the child environment.' ) ;
214+ }
215+
201216 // If forked, report to the parent.
202217 if ( process . send ) {
203218 process . send ( {
@@ -213,6 +228,20 @@ class Benchmark {
213228 this . originalOptions . setup ( this . queue ) ;
214229 }
215230
231+ // Enforcing the permission model removes the environment variables
232+ // --allow-env does not grant access to at startup, which would drop the
233+ // NODE_RUN_BENCHMARK_FN set below. The child only ever sees the
234+ // environment this process hands it, so granting access to all of it does
235+ // not widen what the benchmark can reach. Audit mode removes nothing, so
236+ // it is left alone to keep its diagnostics intact.
237+ const childExecArgv = this . flags . concat ( process . execArgv ) ;
238+ const enforcesPermission = ( arg ) =>
239+ arg === '--permission' || arg . startsWith ( '--permission=' ) ;
240+ if ( childExecArgv . some ( enforcesPermission ) &&
241+ ! childExecArgv . some ( ( arg ) => arg . startsWith ( '--allow-env' ) ) ) {
242+ childExecArgv . push ( '--allow-env=*' ) ;
243+ }
244+
216245 const recursive = ( queueIndex ) => {
217246 const config = this . queue [ queueIndex ] ;
218247
@@ -233,7 +262,7 @@ class Benchmark {
233262
234263 const child = child_process . fork ( require . main . filename , childArgs , {
235264 env : childEnv ,
236- execArgv : this . flags . concat ( process . execArgv ) ,
265+ execArgv : childExecArgv ,
237266 } ) ;
238267 child . on ( 'message' , sendResult ) ;
239268 child . on ( 'close' , ( code ) => {
0 commit comments