Skip to content

Commit

Permalink
Add trust also for import_list() ref #406 (#417)
Browse files Browse the repository at this point in the history
* Add `trust` also for `import_list()` ref #406

* Add tests

* Update doc

* Use .import.rio_rdata
  • Loading branch information
chainsawriot authored May 16, 2024
1 parent ca019c9 commit 0310e20
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 6 deletions.
1 change: 1 addition & 0 deletions R/import.R
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#'
#' After importing metadata-rich file formats (e.g., from Stata or SPSS), it may be helpful to recode labelled variables to character or factor using [characterize()] or [factorize()] respectively.
#'
#' # Trust
#' For serialization formats (.R, .RDS, and .RData), please note that you should only load these files from trusted sources. It is because these formats are not necessarily for storing rectangular data and can also be used to store many things, e.g. code. Importing these files could lead to arbitary code execution. Please read the security principles by the R Project (Plummer, 2024). When importing these files via `rio`, you should affirm that you trust these files, i.e. `trust = TRUE`. See example below. If this affirmation is missing, the current version assumes `trust` to be true for backward compatibility and a deprecation notice will be printed. In the next major release (2.0.0), you must explicitly affirm your trust when importing these files.
#'
#' @note For csv and txt files with row names exported from [export()], it may be helpful to specify `row.names` as the column of the table which contain row names. See example below.
Expand Down
6 changes: 3 additions & 3 deletions R/import_list.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#' @param rbind_fill If `rbind = TRUE`, a logical indicating whether to set the `fill = TRUE` (and fill missing columns with `NA`).
#' @param \dots Additional arguments passed to [import()]. Behavior may be unexpected if files are of different formats.
#' @inheritParams import
#' @inheritSection import Trust
#' @inherit import references
#' @return If `rbind=FALSE` (the default), a list of a data frames. Otherwise, that list is passed to [data.table::rbindlist()] with `fill = TRUE` and returns a data frame object of class set by the `setclass` argument; if this operation fails, the list is returned.
#' @details When file is a vector of file paths and any files are missing, those files are ignored (with warnings) and this function will not raise any error.
#' @examples
Expand Down Expand Up @@ -84,9 +86,7 @@ import_list <- function(file, setclass = getOption("rio.import.class", "data.fra
file <- remote_to_local(file)
}
if (get_info(file)$format == "rdata") {
e <- new.env()
load(file, envir = e)
return(as.list(e))
return(.import.rio_rdata(file = file, .return_everything = TRUE, ...))
}
if (!get_info(file)$format %in% c("html", "xlsx", "xls", "zip")) {
which <- 1
Expand Down
6 changes: 5 additions & 1 deletion R/import_methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,13 @@ import_delim <- function(file, which = 1, sep = "auto", header = "auto", strings
}

#' @export
.import.rio_rdata <- function(file, which = 1, envir = new.env(), trust = getOption("rio.import.trust", default = NULL), ...) {
.import.rio_rdata <- function(file, which = 1, envir = new.env(), trust = getOption("rio.import.trust", default = NULL), .return_everything = FALSE, ...) {
.check_trust(trust, format = "RData")
load(file = file, envir = envir)
if (isTRUE(.return_everything)) {
## for import_list()
return(as.list(envir))
}
if (missing(which)) {
if (length(ls(envir)) > 1) {
warning("Rdata file contains multiple objects. Returning first object.")
Expand Down
6 changes: 4 additions & 2 deletions man/import.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions man/import_list.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions tests/testthat/test_trust.R
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,22 @@ test_that("`trust` wont cause problems for other import methods", {
expect_error(import(iris_file, trust = FALSE), NA)
})
})

test_that("`trust` for import_list()", {
withr::with_tempfile("iris_file", fileext = ".rdata", code = {
export(iris, iris_file)
lifecycle::expect_deprecated(import_list(iris_file), regexp = "set to FALSE by default")
expect_silent(import_list(iris_file, trust = TRUE))
expect_error(import_list(iris_file, trust = FALSE))

})
})

test_that("`trust` wont cause problems for other formats in import_list", {
withr::with_tempfile("data_file", fileext = ".xlsx", code = {
export(list(a = mtcars, b = iris), data_file)
expect_silent(import(data_file))
expect_silent(import(data_file, trust = TRUE))
expect_error(import(data_file, trust = FALSE), NA)
})
})

0 comments on commit 0310e20

Please sign in to comment.