gptr_risk() is the advisory static classifier behind gptr's permission prompts. It reads
code without evaluating it and labels each effect it can see with a level from 0 (known
read-only) to 4 (critical) and a category (read, object_write, file_write,
file_delete, network, process, install, dynamic, session, secret,
interactive, critical, control, plus unlisted for functions the risk tables do not
list). Level 0 is only what the tables know to be read-only; code whose function is computed
at run time is level 3. It cannot see S4 methods, compiled code, package load hooks
or the files source() reads: it decides when gptr asks you, it is not a security boundary.
Arguments
- code
R code: a character vector, a call or an expression.
- envir
NULLor the environment the code would run in. When given, assignments to existing bindings are reported as overwrites with their size (object.size()in a leaf; promises and active bindings are never forced) and user-defined functions called by the code are classified through their bodies.- root
The project root used for path classes;
NULLmeans the current project root.
Value
A gptr_risk object: a list with level (integer 0-4), label, categories,
flagged (a data frame with columns call, fn, level, category, path,
path_class), paths, secret, secret_guard, assigned, dynamic, and the additive
fields sizes (bytes of overwritten objects, by name), secrets (guarded secret names),
kind and parse_error.
Details
Paths are classified relative to root (workspace, temp, outside, protected,
control, instructions, critical, url, wildcard, unknown). Calls of
peter$sh(), system(), system2() and processx::run() with literal commands are
classified with the command table (inst/extdata/risk-commands.csv), peter$sql() by its
statements and peter$py() by a token scan. Plugins and users extend both tables with
risk_rule records.
Examples
gptr_risk("unlink('data', recursive = TRUE)")$level
#> [1] 3
gptr_risk("summary(mtcars)")
#> risk 0 (read-only)
e = new.env()
e$df = data.frame(a = 1:3)
gptr_risk("df = head(df, 2)", envir = e)$flagged
#> call fn level category path path_class
#> 1 overwrites `df` <data.frame, 744 B> <NA> 2 object_write <NA> <NA>