@@ -391,17 +391,26 @@ function isBackslashInterpreterToken(token: string): boolean {
391391 return base . startsWith ( "\\" ) && SHELL_INTERPRETERS . has ( base . slice ( 1 ) ) ;
392392}
393393
394+ function shellPayloadReferencesPositional ( payload : string ) : boolean {
395+ return / \$ (?: [ 0 - 9 @ * # ] | \{ (?: [ 0 - 9 ] + | [ @ * # ] ) \} ) / . test ( payload ) ;
396+ }
397+
394398function nestedInterpreterPayloadOpaque ( payload : string , rest : readonly string [ ] ) : boolean {
395399 if ( isBackslashInterpreterToken ( payload ) ) return true ;
396400 const first = tokenize ( payload ) [ 0 ] ;
397401 if ( first !== undefined && isBackslashInterpreterToken ( first ) ) return true ;
402+ // The payload can execute trailing argv through $0/$1/... substitution, so
403+ // the payload alone is not a faithful subject for dependency-install policy.
404+ if ( rest . length > 0 && shellPayloadReferencesPositional ( payload ) ) return true ;
398405 // Trailing tokens after the -c payload: allow only plain positionals.
399406 // `-c`, redirects, backslashes, or flags mean the quoted body was split and
400407 // the truncated payload must not be trusted on its own under auto.
401408 if ( rest . length > 0 && ! rest . every ( isSafeShellPositional ) ) return true ;
402409 return false ;
403410}
404411
412+ const SHELL_SEPARATE_VALUE_FLAGS = new Set ( [ "-O" , "-o" ] ) ;
413+
405414function peelShellDashC ( tokens : string [ ] , start : number ) : PeelOutcome {
406415 let i = start ;
407416 while ( i < tokens . length ) {
@@ -424,6 +433,10 @@ function peelShellDashC(tokens: string[], start: number): PeelOutcome {
424433 if ( nestedInterpreterPayloadOpaque ( payload , [ ] ) ) return { kind : "opaque" } ;
425434 return { kind : "inner" , command : payload } ;
426435 }
436+ if ( SHELL_SEPARATE_VALUE_FLAGS . has ( t ) ) {
437+ i += 2 ;
438+ continue ;
439+ }
427440 // Clustered short flags that include `c` (`-lc`, `-ic`, …): `c` takes the
428441 // next token as the command string, matching bash/sh/zsh.
429442 if ( / ^ - [ A - Z a - z ] * c [ A - Z a - z ] * $ / . test ( t ) ) {
0 commit comments