Skip to content

SARIF invocation properties from InvocationContext #1795

@KalleOlaviNiemitalo

Description

@KalleOlaviNiemitalo

I have a tool that uses System.CommandLine and can create a Static Analysis Results Interchange Format (SARIF) Version 2.1.0 log file. SARIF defines the invocation.commandLine, invocation.arguments, and invocation.responseFiles properties in which the tool can save information about how it was invoked. I'd like to implement that in the tool. I am not requesting any changes in System.CommandLine for this purpose, but I am curious if anyone else has implemented something similar.

It would be easy to use string[] args from the Main method for the SARIF invocation.arguments property, and Environment.CommandLine for the SARIF invocation.commandLine property. However, I hope I can instead get the information from System.CommandLine somehow, for these reasons:

  • System.CommandLine parses the response file syntax, and I'd rather not reimplement that parsing just for the sake of the SARIF invocation.responseFiles property, especially if the syntax can change later (Does not allow arguments that start with the '@' character #1625).
  • If the command line contains passwords or other sensitive information, then those should be redacted from the log file. I hope I can somehow mark the Argument<T> and Option<T> instances as sensitive and then redact the values if SymbolResult.Symbol is so marked. I can imagine several ways to mark them:
    • During initialization, create a List<Symbol> that contains all the sensitive Argument<T> and Option<T> instances.
    • Derive classes SensitiveArgument<T> and SensitiveOption<T>. Having to forward the constructors would be a bit annoying.
    • Define struct SensitiveString, and use Argument<SensitiveString> and Option<SensitiveString>. (Alternatively SecureString, but that is cumbersome to use and no longer recommended.)
    • Add a marker ICompletionSource to Argument.Completions. That would be somewhat weird.

For the SARIF invocation.arguments property, there are ParseResult.Directives and ParseResult.Tokens, which would let the tool check the sensitivity markers, but I cannot fully reconstruct the original string[] args from them:

  • The order of directives is not preserved. I suppose that wouldn't be a problem in practice, but it feels a bit dirty.
  • No public way to distinguish between --option=value, --option:value, and --option value. Non-public reflection could perhaps do it by checking whether both tokens have the same Token.Position. As above, the difference shouldn't matter in practice.
  • No obvious way to know which tokens came from response files, or which response files were even used. Could be worked around by disabling response files. (The tool doesn't need very long command lines because it reads configuration files.)

So, it seems I can make the tool log a invocation.arguments property that is good enough although not quite perfect, but I cannot make it log invocation.commandLine (too difficult to redact) nor invocation.responseFiles (too difficult to find which files were used, and the tokens from the files will be in invocation.arguments).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions