@@ -234,7 +234,132 @@ function setupUncaughtExceptionCapture(exceptionHandlerState,
234234 } ;
235235}
236236
237+ const replaceUnderscoresRegex = / _ / g;
238+ const leadingDashesRegex = / ^ - - ? / ;
239+ const trailingValuesRegex = / = .* $ / ;
240+
241+ // Save references so user code does not interfere
242+ const replace = Function . call . bind ( String . prototype . replace ) ;
243+ const has = Function . call . bind ( Set . prototype . has ) ;
244+ const test = Function . call . bind ( RegExp . prototype . test ) ;
245+
246+ // This builds the initial process.allowedNodeEnvironmentFlags
247+ // from data in the config binding.
248+ function buildAllowedFlags ( ) {
249+ const {
250+ envSettings : { kAllowedInEnvironment }
251+ } = internalBinding ( 'options' ) ;
252+ const { options, aliases } = require ( 'internal/options' ) ;
253+
254+ const allowedNodeEnvironmentFlags = [ ] ;
255+ for ( const [ name , info ] of options ) {
256+ if ( info . envVarSettings === kAllowedInEnvironment ) {
257+ allowedNodeEnvironmentFlags . push ( name ) ;
258+ }
259+ }
260+
261+ for ( const [ from , expansion ] of aliases ) {
262+ let isAccepted = true ;
263+ for ( const to of expansion ) {
264+ if ( ! to . startsWith ( '-' ) || to === '--' ) continue ;
265+ const recursiveExpansion = aliases . get ( to ) ;
266+ if ( recursiveExpansion ) {
267+ if ( recursiveExpansion [ 0 ] === to )
268+ recursiveExpansion . splice ( 0 , 1 ) ;
269+ expansion . push ( ...recursiveExpansion ) ;
270+ continue ;
271+ }
272+ isAccepted = options . get ( to ) . envVarSettings === kAllowedInEnvironment ;
273+ if ( ! isAccepted ) break ;
274+ }
275+ if ( isAccepted ) {
276+ let canonical = from ;
277+ if ( canonical . endsWith ( '=' ) )
278+ canonical = canonical . substr ( 0 , canonical . length - 1 ) ;
279+ if ( canonical . endsWith ( ' <arg>' ) )
280+ canonical = canonical . substr ( 0 , canonical . length - 4 ) ;
281+ allowedNodeEnvironmentFlags . push ( canonical ) ;
282+ }
283+ }
284+
285+ const trimLeadingDashes = ( flag ) => replace ( flag , leadingDashesRegex , '' ) ;
286+
287+ // Save these for comparison against flags provided to
288+ // process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
289+ // Avoid interference w/ user code by flattening `Set.prototype` into
290+ // each object.
291+ const nodeFlags = Object . defineProperties (
292+ new Set ( allowedNodeEnvironmentFlags . map ( trimLeadingDashes ) ) ,
293+ Object . getOwnPropertyDescriptors ( Set . prototype )
294+ ) ;
295+
296+ class NodeEnvironmentFlagsSet extends Set {
297+ constructor ( ...args ) {
298+ super ( ...args ) ;
299+
300+ // the super constructor consumes `add`, but
301+ // disallow any future adds.
302+ this . add = ( ) => this ;
303+ }
304+
305+ delete ( ) {
306+ // noop, `Set` API compatible
307+ return false ;
308+ }
309+
310+ clear ( ) {
311+ // noop
312+ }
313+
314+ has ( key ) {
315+ // This will return `true` based on various possible
316+ // permutations of a flag, including present/missing leading
317+ // dash(es) and/or underscores-for-dashes.
318+ // Strips any values after `=`, inclusive.
319+ // TODO(addaleax): It might be more flexible to run the option parser
320+ // on a dummy option set and see whether it rejects the argument or
321+ // not.
322+ if ( typeof key === 'string' ) {
323+ key = replace ( key , replaceUnderscoresRegex , '-' ) ;
324+ if ( test ( leadingDashesRegex , key ) ) {
325+ key = replace ( key , trailingValuesRegex , '' ) ;
326+ return has ( this , key ) ;
327+ }
328+ return has ( nodeFlags , key ) ;
329+ }
330+ return false ;
331+ }
332+ }
333+
334+ Object . freeze ( NodeEnvironmentFlagsSet . prototype . constructor ) ;
335+ Object . freeze ( NodeEnvironmentFlagsSet . prototype ) ;
336+
337+ return process . allowedNodeEnvironmentFlags = Object . freeze (
338+ new NodeEnvironmentFlagsSet (
339+ allowedNodeEnvironmentFlags
340+ ) ) ;
341+ }
342+
343+ function setupAllowedFlags ( ) {
344+ Object . defineProperty ( process , 'allowedNodeEnvironmentFlags' , {
345+ get : buildAllowedFlags ,
346+ set ( value ) {
347+ // If the user tries to set this to another value, override
348+ // this completely to that value.
349+ Object . defineProperty ( this , 'allowedNodeEnvironmentFlags' , {
350+ value,
351+ configurable : true ,
352+ enumerable : true ,
353+ writable : true
354+ } ) ;
355+ } ,
356+ enumerable : true ,
357+ configurable : true
358+ } ) ;
359+ }
360+
237361module . exports = {
362+ setupAllowedFlags,
238363 setupAssert,
239364 setupCpuUsage,
240365 setupHrtime,
0 commit comments