Configuration files

A configuration file is analogous to a .travis.yml file. It describes how a C or C++ project should be analyzed with TrustInSoft Analyzer.

It also allows to configure the analysis by defining the list of source files to analyze or by setting any other options of the analyzer (such as the slevel).

It is recommended to use the suffix .config (such as tis.config) for the configuration files in order to be automatically recognized and selected in the GUI. However, any filename can be used for a configuration when using the -tis-config-load <filename> option.

See the section Syntax to know how to write a configuration file.

Analysis configurations

A single configuration file can describe one or several analysis for the same project. These descriptions are called analysis configurations.

By default, the first analysis configuration of the file is used. This behavior can be changed with the option -tis-config-select <n> where <n> is the *n*-th analysis configuration in the file (starting at 1).

In the GUI, if the selected configuration file has several analysis configuration, a second field will be displayed to allow the user to select another analysis configuration.

Analysis configuration selection in the GUI

Tip

An analysis configuration can also be selected by its name thanks to the -tis-config-select-by-name command line option.

Syntax

The configuration file is written in JSON, according to the ECMA-404 standard, with a syntax extension for comments. The syntax extension allows the following comments syntax:

  • // will ignore the end of the line

  • /* will ignore all characters until the next */

Caution

Conforming to the ECMA-404 standard, objects are lists of name/value pairs and the names are not required to be unique.

Moreover, the ordering of the name/value pairs is significant for configuration files.

A configuration file is a list (i.e. a JSON array) of analysis configurations. An analysis configuration is represented as a JSON object where each option is a pair “name/value” of this JSON object:

[
  // analysis configuration 1
  {
    "option1": <value_of_option1>,
    "option2": <value_of_option2>,
    // …
  },
  // analysis configuration 2
  {
    "option2": <another_value_of_option2>
  },
  // …
]

If your configuration file contains only one analysis configuration, it can also be directly written without the top-level JSON array:

{
  "option1": <value_of_option1>,
  "option2": <value_of_option2>,
  // …
}

Tip

A configuration file included with the special option include must contain only a single analysis configuration.

Loading an analysis configuration

When loading an analysis configuration, the options described in the configuration will be set in the analyzer. The evaluation order is done from left to right and options are set according to this evaluation order.

Some options defined in a configuration file can also be set by the command line or by the GUI. In this case, the following rules are applied:

  • If the option has a simple type (string, boolean, number), then any previous value (set by the command line or the GUI) is overwritten.

  • If the option has a list type, then the value from the analysis configuration is concatenated at the end of the list of any previous value set by the command line or the GUI.

  • If the option has a collection type (set, map, …), then the value from the analysis configuration is merged with any previous value set by the command line or the GUI. This behavior can be disabled by adding the -@all keyword at the beginning of the value (see also Options with set/list type argument, Options with map type argument and Options with multiple map type argument).

See also the Variables about the type of each option.

Example:

$ cat tis.config
{ "main": "my_main",
  "val-slevel-merge-after-loop": [ "-@all", "f" ],
  "slevel-function": { "f": 10 } }

$ tis-analyzer \
    -main foo \
    -val-slevel-merge-after-loop "main,foo" \
    -slevel-function "main:50" \
    -tis-config-load tis.config

In this example, the analysis is performed with the following options:

  • main: my_main

  • val-slevel-merge-after-loop: f

  • slevel-function: main:50 and f:10

Changing the analysis configuration

When another analysis configuration is loaded, before being loaded, the previous one needs to be reset.

When an analysis configuration is reset, any value set by the configuration is reverted to its previous value as if the analysis configuration was never loaded. However if a value has been changed after loading the analysis configuration by using the GUI or anything else, then this updated value will not be reset.

Then, once the previous analysis configuration is reset, the new one is loaded with the same rules as described in Loading an analysis configuration.

Downloading the current configuration

In the GUI, the current configuration can be downloaded with the button at the right of the Help button (see the above screenshot).

The downloaded configuration file contains the values of all options.

Unset options (or options with their default values) are not saved in the configuration file.

Caution

Some options, such as the list of files, require the Parsing or Value Analysis to be run in order to be correctly synchronized with the current analysis.

It is recommended to download the configuration file when both of the Parsing and Value Analysis buttons of the Overview panel are not notifying that some parameters are out-of-date.

Tip

In the downloaded configuration file, some options values are made explicit. For instance, the files options always contains the explicit list of files instead of the "all" value even if it matches the same list of files.

Path in analysis configurations

Some options in the analysis configurations can contain path to files, such as the options files or cpp-extra-args (when a -I     <dir> is given for example).

Every relative path detected in these options is relative to the directory containing the configuration file, except when the analysis configuration has the special option prefix_path.

In that case, if the prefix_path value is an absolute path, then the detected relative paths are relative to the prefix_path. Otherwise, the resolved relative path is relative to <directory of the configuration file>/<prefix_path>

All absolute paths detected are left unchanged.

Variables

In configuration files, variables can be defined in a variables field and then used in any field of the configuration with the ${VARIABLE_NAME} syntax:

[ { "name": "My first analysis - ${MAIN}",
    "variables": {
      "LIBDIR": "./src/lib/",
      "MAIN": "driver_main"
     },
    "files:" [
      "${LIBDIR}/scp.c",
      "${LIBDIR}/ssh.c",
      "./test/test.c"
    ]
    "cpp-extra-args": "-I${LIBDIR}",
    "main": "${MAIN}",
    "slevel-function": {
      "${MAIN}": 50
    } } ]

If a same variable is defined twice, only the latest definition is kept.

Tip

Variable names are case insensitive.

In addition of variables defined in the variables field, the following variables are automatically available (and cannot be overwritten):

  • ${NAME}: Replaced by the analysis name. This variable is not available if the analysis configuration does not have a name.

  • ${NUMBER}: Replaced by the index of the analysis configuration inside the configuration file (starting at 1). This variable is always available.

  • ${MACHDEP}: Replaced by the value of the machdep field. This variable is not available if the analysis configuration does not have a machdep field.

  • ${TIS_KERNEL_SHARE}: Replaced by the value given by tis-analyzer -print-share-path, useful to access files of TrustInSoft’s libc.

Caution

The value of variables are evaluated after parsing the analysis configuration. Hence, the value of ${MACHDEP} in the following example is x86_16:

[ { "machdep": "gcc_x86_64",
    "name": "Analysis for ${MACHDEP}",
    "machdep": "x86_16" } ]

Caution

Using variables is not allowed in the following fields: - include - prefix_path - in keys of the variables field

Variables can be used in other variables definition, but a variable cannot dependent on itself to be evaluated:

// Allowed
[ { "variables": {
      "A": "${B}",
      "B": "something" } } ]

// NOT allowed
[ { "variables": {
      "A": "${B}",
      "B": "${C}",
      "C": "${A}" /* cyclic dependency: A -> B -> C -> A */ } } ]

When the include field is used, since the evaluation of variables is done after parsing the configuration, all variables defined in both the including and included configurations are available in both the including and included configurations:

// In config.json:
[ { "variables": {
      "A": "${B}",
      "C": "test" },
    "include": "include.json" /* Defines "${B}" */ } ]

// In include.json:
[ { "variables": { "B": "something" },
    "main": "${C}" /* coming from config.json */ } ]

Warning

In the above example, if a configuration file includes include.json without defining C, an error will be raised asking C to be defined.

List of options

Option name

  • Description: This option allows to give a name to the analysis configuration. This name is used in the GUI field to select the analysis configuration if the configuration file contains several ones, which can be more convenient than its number.

    The name can also be used to select an analysis configuration from the command line with the -tis-config-select-by-name option.

    The given name is cosmetic and has no impact on the performed analysis.

  • Type: string

Example:

[
  {
    "name": "configuration_name_1",
    "files": [
        "file_name_1.c",
        "file_name_2.c"
      ]
  },
  {
    "name": "configuration_name_2",
    "files": [
      {
        "name": "file_name_1.c",
        "cpp-extra-args": [
            "-I./include/"
        ]
      },
      {
        "name": "file_name_3.c"
      }
    ]
  }
]

Usage:

tis-analyzer -tis-config-load tis.config -tis-config-select-by-name \
  configuration_name_1
tis-analyzer -tis-config-load tis.config -tis-config-select-by-name \
  configuration_name_2

Tip

You can switch from one configuration to another in the GUI, using the Analysis configuration to run combo-box

Option files

  • Description: The collection of files to analyze. Accepts either a list of file paths or the value "all". Listed file paths are relative to the location of the configuration file (or the prefix_path value if set) and may contain the wildcard * to match any string. The value "all" selects all source files contained in the directory of the configuration file, or, if prefix_path is set, all source files in prefix_path. If this field is set in a configuration file, all other source files given on the command line will be ignored.

    Examples:

    { "files": "all" }
    
    { "files": [ "src/aes.c", "main.c" ] }
    
    { "files": [ "src/*.c", "main.c" ] }
    
    { "files":
      [ { "name": "src/aes.c",
          "cpp-extra-args": "-I include -D ARG=2" },
        "main.c" ] }
    

    Note: Use the cpp-extra-args field to add extra arguments to the pre-processor command for every file.

  • Type:

    • string among the following values:

      • “all”

    • list of:

      • strings

      • objects with fields:

        • name (required): The name of the file.

          Type: string

        • cpp-command (optional): The command to use to pre-process the file. See also the -cpp-command-file command line option. Beware: relative paths in this field are kept unchanged (and are relative to the analyzer working directory and not the configuration file directory). The special option prefix_path does not affect paths of this field either. Use the cpp-extra-args field instead for options involving a path.

          Type: string

        • cpp-extra-args (optional): The extra arguments to add to the pre-processor command for the file. See also the -cpp-extra-args-file command line option. however only relevant options for pre-processing are kept. Relative paths are affected by the directory containing the configuration file and the prefix_path field.

          Type: string

Option filesystem

  • Description: The virtual file system and its options to use for the analysis. See also tis-mkfs Manual. If the object of this field does not contain a "files" or "use", and if "enabled" is set to true, then a default empty filesystem is used.

  • Type: object with fields:

    • enabled (optional): If enabled, the virtual file system is used during the analysis. If the feature is disabled, it can still be enabled later from the GUI. Default true.

      Type: boolean

    • system-errors (optional): If set, system errors are simulated while accessing the file system. Default: value of the option -fs-error.

      Type: boolean

    • files (optional): The list of files in the virtual file system. This list can be empty. This field is not compatible with the "use" one.

      Type: list of:

      • strings

      • objects with fields:

        • name (required): Name of the file (or directory) in the virtual file system. It should exactly match the string given to the filesystem functions in the C code.

          Type: string

        • type (optional): Type of the abstract file. The supported files are regular files ("reg"), directories ("dir"), named pipes ("fifo") and character devices ("chr"). If the type is not specified, then a regular file will be created, except if "from" is used and points to a directory.

          Type: string among the following values:

          • “chr”

          • “dir”

          • “fifo”

          • “reg”

        • from (optional): If given, the content of the file (or directory) in the virtual file system will be the one of the real file located at the given path. If not given, the content of the file (or directory) will be abstracted. See more at File Generation. Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special option prefix_path.

          Type: string

        • min-size (optional): First argument of the -generic option of tis-mkfs. It represents the minimal size in bytes of the file. See more at File Generation. This field is not compatible with "from". Fields "max-size", "min-content" and "max_content" are also required if this one is given.

          Type: integer

        • max-size (optional): Second argument of the -generic option of tis-mkfs. It represents the maximal number of bytes of the file. See more at File Generation. This field is not compatible with "from". Fields "min-size", "min-content" and "max-content" are also required if this one is given.

          Type: integer

        • min-content (optional): Third argument of the -generic option of tis-mkfs. It represents the minimal value of the interval for each character of the file. See more at File Generation. This field is not compatible with "from". Fields "min-size", "max-size" and "max-content" are also required if this one is given.

          Type: integer

        • max-content (optional): Fourth argument of the -generic option of tis-mkfs. It represents the maximal value of the interval for each character of the file. See more at File Generation. This field is not compatible with "from". Fields "min-size", "max-size" and "min-content" are also required if this one is given.

          Type: integer

    • incoming-connections (optional): The list of incoming connections that are selected each time "accept" is called.

      Type: list of objects with fields:

      • type (required): First argument of the -incoming-connection (or -outgoing-connection) option of tis-mkfs. It defines the type of socket that used by the peer.

        Type: string among the following values:

        • “UNIX”

      • address (required): Second argument of the -incoming-connection (or -outgoing-connection). It defines the address of the peer.

        Type: string

      • port (optional): Port port used for the connection. Must be defined if the connection type is "INET"

        Type: integer

      • from (optional): If given, the data read from the socket will be content of the real file pointed to by the given path. Incompatible with "min-content" and "max-content". Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special option prefix_path.

        Type: string

      • min-content (optional): If given, it represents the minimal value of the interval for each character read from the socket. Requires "max-content" to be set as well. This field is not compatible with "from".

        Type: integer

      • max-content (optional): If given, it represents the maximal value of the interval for each character read from the socket. Requires "min-content" to be set as well. This field is not compatible with "from".

        Type: integer

      • chunks (optional): If given, each read operation on the socket will successfully read this much bytes. This allows to model partial read operations.

        Type: list of integers

    • outgoing (optional): The list of outgoing connections that are selected each time "connect" is called.

      Type: list of objects with fields:

      • type (required): First argument of the -incoming-connection (or -outgoing-connection) option of tis-mkfs. It defines the type of socket that used by the peer.

        Type: string among the following values:

        • “UNIX”

      • address (required): Second argument of the -incoming-connection (or -outgoing-connection). It defines the address of the peer.

        Type: string

      • port (optional): Port port used for the connection. Must be defined if the connection type is "INET"

        Type: integer

      • from (optional): If given, the data read from the socket will be content of the real file pointed to by the given path. Incompatible with "min-content" and "max-content". Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special option prefix_path.

        Type: string

      • min-content (optional): If given, it represents the minimal value of the interval for each character read from the socket. Requires "max-content" to be set as well. This field is not compatible with "from".

        Type: integer

      • max-content (optional): If given, it represents the maximal value of the interval for each character read from the socket. Requires "min-content" to be set as well. This field is not compatible with "from".

        Type: integer

      • chunks (optional): If given, each read operation on the socket will successfully read this much bytes. This allows to model partial read operations.

        Type: list of integers

    • nb-max-files (optional): The maximum number of files that can be created by the program during the analysis. This field is relevant only if the "files" is given. Default: 20.

      Type: integer

    • nb-max-dirs (optional): The maximum number of directories that can be created by the program during the analysis. This field is relevant only if the "files" is given. Default: 20.

      Type: integer

    • generated-filename (optional): The name of the generated C file containing the virtual file system. This field is relevant only if the "files" is given. Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special option prefix_path. Default: "tis-mkfs-filesystem.c".

      Type: string

    • use (optional): Name of a tis-mkfs generated C file to use instead of a list of files. This field is not compatible with the "files" one. Note: if given, this filename is relative to the configuration file directory (unless the filename is absolute), and also depends on the special option prefix_path.

      Type: string

Option language

  • Description: The language to use for the analysis.

    Setting a language allows to automatically set a list of options to correctly analyzing the program according to the given language.

    The language is set after any other options of the configuration file, hence the list of options set by this language cannot be overwritten by a field of the configuration file.

    The auto value allows to decide which language to use according to the given list of source files.

    Note: If this field is not given, the behavior is the same as the auto value.

    Note: The automatic detection of the language is only performed if a configuration file is read. Using the analyzer with the command line without a configuration file will not perform the automatic detection of the language.

  • Type: string among the following values:

    • “auto”

    • “c”

    • “c++”

Option prefix_path

  • Description: Prepend all file paths in the configuration with a (relative) path prefix.

    Ordinarily, all file paths in the configuration are relative to the directory containing the configuration file. If prefix_path is declared, all relative file paths in the configuration file are treated as if they were prefixed by <path to directory containing the configuration file>/<prefix_path>.

    The prefix_path option can be declared with an absolute path, but this is not recommended. In such cases, all paths in the configuration file are treated as if they were prepended by the given absolute path verbatim.

    Tip

    If the value of the option files is all, then only files located in the given prefix_path are selected.

  • Type: string

Example: The following configuration file specified a prefix path:

{
  "prefix_path": "src/dir",
  "files": [ "file1.c", "file2.c" ],
  "cpp-extra-args": "-DFOO=4 -Iheaders"
}

In effect, the analysis sees the following values for each option:

  • for option files: [ "src/dir/file1.c", "src/dir/file2.c" ],

  • for option cpp-extra-args: "-DFOO=4 -Isrc/dir/headers".

Warning

The prefix_path option is not propagated when options are imported form one configuration into another via the include option.

Option include

  • Description: Import a configuration from a separate file into the current analysis configuration.

    Warning

    The included file must contain exactly one analysis configuration.

    { "include": "path/to/another_configuration_file.config" }
    

    Options defined in the included configuration extend or override the options in the current configuration depending on the type of the imported option and the position of the same option in the current configuration relative to the include statement.

    • Option prefix_path is ignored: it is never propagated from the included configuration to the including configuration.

    • For each option that takes a collection of values (types list, map and set), the imported values are concatenated with the values defined in the including analysis configurations, in the following order:

      1. values declared in the including configuration before the include statement, followed by

      2. values declared in the included configuration, followed by

      3. values declared in the including configuration after the include statement.

    • For each option that takes a single value (types: string, integer, boolean), the imported value either overrides or is overridden by values in the including configuration:

      • options in the included configuration override options defined before the include statement in the including configuration, but

      • options in the included configuration are overridden by options defined after the include statement in the including configuration.

    The include option can be invoked multiple times to import multiple configuration files. Each include statement follows the concatenations/overriding rules above. The include option can also be used to import multiple files in a single declaration by passing it a list of paths as an argument instead of a path. In that case the configurations are imported in succession in the order they appear in the list, as if each file was included separately.

  • Type:

    • string

    • list of strings

Example: Included configuration (imported.json):

{
  "files": [ "file1.c", "file2.c", "file3.c" ]
}

Including configuration:

[
  { 
    "files": [ "fileA.c" ],
    "include": "imported.json",
    "files": [ "fileB.c" ],
  }
]

The value of files during analysis is:

[ "fileA.c", "file1.c", "file2.c", "file3.c", "fileB.c" ]

Example: Included configuration (imported.json):

{
  "slevel": 100,
  "main": "test1"
}

Including configuration:

{
  "slevel": 10,
  "include": "imported.json",
  "main": "test2"
}

The value of slevel during analysis is 100 and the value of main during the analysis is test2.

Example: Included configuration (imported1.json):

{
  "files": [ "file1.c" ]
}

Included configuration (imported2.json):

{
  "files": [ "file2.c" ]
}
[
  { 
    "files": [ "fileA.c" ],
    "include": [ "imported1.json", "imported2.json" ],
    "files": [ "fileB.c" ]
  }
]

The value of files during analysis is:

[ "fileA.c", "file1.c", "file2.c", "fileB.c" ]

Command line options

The command line options allowing to tune the analyzer can also be given in the configuration file. The command line option name needs to be written without the leading dash - (such as slevel-function instead of -slevel-function).

Caution

The command line options involving a special action at the start of the analyzer (-load, -add-path, -save, -tis-config, …), options involving an action which prematurely terminates the analyzer (-dump-cmdline, …), project-related options (-set-project-as-default, …), and sequencing options (-then, -then-on, …) are not supported in configuration files.

Options with simple type argument

Any command line option taking none, an integer or a string as argument can be written with respectively a boolean, an integer or a string JSON value.

Example: The following command line

tis-analyzer -val -slevel 100 -main my_function

is equivalent to the following analysis configuration

{
   "val": true,
   "slevel": 100,
   "main": "my_function"
}

When defining such an option, any previous value bound to this option is overwritten by the new defined one, including the value given on the command line if any.

Tip

The hexadecimal representation for integer options can also be used with the following syntax:

{ "slevel": "0x100" }

Options with set/list type argument

Any command line option taking a set or a list of values as argument, with the support of categories if available, can be written with a list of JSON values.

When defining such a set option, the newly defined value is merged with any previously defined value, including the ones given on the command line.

In the case of a list option, the newly defined value is concatenated at the end of the previous value, including the ones given on the command line too.

Tip

For set options, as specified in documentation of command line options, the keyword "-@all" can be used to remove any previous value of the set.

This keyword is not available for list options.

Example: The following command line:

tis-analyzer
  -cpp-extra-args=-Iinclude/
  -cpp-extra-args=-DFN(a\,b)=my_function(a\,b)
  -val-slevel-merge-after-loop "@all,-main"

is equivalent to the following analysis configuration:

{
   "cpp-extra-args":
     [
       "-Iinclude/",
       "-DFN(a,b)=my_function(a,b)"
     ],
   "val-slevel-merge-after-loop":
     [
       "@all",
       "-main"
     ]
}

Warning

With the command-line, any , in the values needs to be escaped to prevent it to be interpreted as a separator for the list/set. Escaping such commas is not required in a configuration file.

Tip

The brackets ([ and ]) can also be omitted if the value of the option contains only one element. Also the same option can be given several times in a same analysis configuration.

Hence, the two following configurations are equivalent:

{ "cpp-extra-args":
    [ "-Iinclude/",
      "-DFN(a,b)=my_function(a,b)" ] }
{ "cpp-extra-args": "-Iinclude/",
  "cpp-extra-args": "-DFN(a,b)=my_function(a,b)" }

Options with map type argument

Any command line option taking a map (also known as dictionary) as argument can be written with a JSON object where:

  • the keys of the map are the field names of the JSON object,

  • and values of these keys are the value of the JSON object (associated to their respective field).

When defining such a map option, the newly bindings defined are merged with any previously defined bindings in the map, including the ones given on the command line.

A binding of the map can be removed from the map by using the value null with the key of the binding as the object field.

If a key is associated to several values, the last defined value overwrites all the previously defined one.

Tip

The binding "-@all": true can be use to remove any binding previously defined in the map.

Example: The following command line

tis-analyzer
  -slevel-function "f:100,g:50,h:56,main:42"
  -slevel-function "f:110,-g"

is equivalent to the following analysis configuration

{
  "slevel-function":
    {
      "f": 100,
      "g": 50,
      "h": 56,
      "main": 42,
      "f": 110,
      "g": null
    }
}

Warning

With the command line, any , in the keys or values needs to be escaped to prevent it to be interpreted as a separator for the list/set. Escaping such commas is not required in a configuration file.

Options with multiple map type argument

Any command line option taking a multiple map as argument can be written with a JSON object where:

  • the keys of the map are the field names of the JSON object,

  • the associated JSON values are JSON arrays containing the value of the corresponding keys. If there is exactly one value, the value can also simply be the corresponding value with no enclosing array.

When defining such a map option, the newly bindings defined are merged with any previously defined bindings in the map, including the ones given on the command line.

A binding of the map can be removed from the map by using the value null with the key of the binding as the object field.

If a key is associated to several values, the concatenation of all values is kept.

Example: The following command line

tis-analyzer
  -a-multimap-option "a:a,c:v1;v2"
  -a-multimap-option "c:v3,-a"

is equivalent to the following analysis configuration

{
  "a-multimap-option":
    {
      "a": "a",
      "c": [ "v1", "v2", "v3" ],
      "a": null
    }
}

which is also equivalent to the following analysis configuration

{
  "a-multimap-option":
    {
      "a": "a",
      "c": "v1",
      "c": "v2",
      "c": "v3",
      "a": null
    }
}

Warning

With the command line, any , in the keys or values needs to be escaped to prevent it to be interpreted as a separator for the list/set. Escaping such commas is not required in a configuration file.

Examples

A basic example compliant with a simple C project:

{
  "files": "all",
  "machdep": "gcc_x86_64",
  "val-stop-at-nth-alarm": 1
}

More advanced examples:

{
  "files":
    [
      "util.c",
      "tool/engine.c",
      "main.c"
    ],
  "main": "f",
  "cpp-extra-args":
    [
      "-DFOO",
      "-Itool"
    ],
  "slevel": 1500
}
{
  "files":
    [
      "crypto.c",
      "main.c"
    ],
  "slevel-function":
    {
      "main":  150,
      "encrypt": 30000
    }
 }
{
  "files":
    [
      "crypto.c",
      "main.c"
    ],
  "filesystem":
    {
      "enabled": true,
      "system_errors": false,
      "files":
        [
          {
            "name": "/home/Documents",
            "type": "dir"
          },
          {
            "name": "/home/bob/.bashrc"
          },
          {
            "name": "/usr/share/input_file.txt",
            "from": "main_input_file.txt"
          }
        ]
    }
 }