From 07e2a9902915eef52ab0b085ca344f1a371dcdf0 Mon Sep 17 00:00:00 2001 From: Yihui Xie Date: Thu, 18 Jan 2024 03:23:58 -0600 Subject: [PATCH] Correctly avoid writing to the input file when there are no preserved HTML chunks (#2535) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Yihui Xie Co-authored-by: Jiří Moravec --- DESCRIPTION | 2 +- NEWS.md | 2 ++ R/html_document_base.R | 7 ++++++- tests/testthat/test-render.R | 9 +++++++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d214d8c684..ea9d965b74 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: rmarkdown Title: Dynamic Documents for R -Version: 2.25.2 +Version: 2.25.3 Authors@R: c( person("JJ", "Allaire", , "jj@posit.co", role = "aut"), person("Yihui", "Xie", , "xie@yihui.name", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-0645-5666")), diff --git a/NEWS.md b/NEWS.md index eb8ca5dfe0..b109439944 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,8 @@ rmarkdown 2.26 - For the output format option `fig_crop: auto`, it will now use the same logic as in **knitr** to decide if cropping is possible (yihui/knitr#2246). +- Avoid corrupting input files by accident (thanks, @J-Moravec, #2534). + rmarkdown 2.25 ================================================================================ diff --git a/R/html_document_base.R b/R/html_document_base.R index a6c86f54c8..d2dff82b1c 100644 --- a/R/html_document_base.R +++ b/R/html_document_base.R @@ -251,7 +251,12 @@ html_document_base <- function(theme = NULL, } extract_preserve_chunks <- function(input_file, extract = extractPreserveChunks) { - input_str <- read_utf8(input_file) + # Don't try to modify the input file if it's not .md, otherwise the original + # input could be corrupted (#2534). In theory, preserved chunks should only + # exist in the intermediate .md file from knit(). If the .md file is not + # intermediate but original, this processing should be harmless. + if (!xfun::file_ext(input_file) %in% c('md', 'markdown')) return() + input_str <- one_string(read_utf8(input_file)) preserve <- extract(input_str) if (!identical(preserve$value, input_str)) write_utf8(preserve$value, input_file) preserve$chunks diff --git a/tests/testthat/test-render.R b/tests/testthat/test-render.R index 47a50f7968..3c7dd424e5 100644 --- a/tests/testthat/test-render.R +++ b/tests/testthat/test-render.R @@ -32,3 +32,12 @@ test_that("file_scope split correctly input file", { expect_snapshot_file(splitted[1]) expect_snapshot_file(splitted[2]) }) + +test_that("Input file is not corrupted", { + input <- tempfile() + on.exit(unlink(input), add = TRUE, after = FALSE) + saveRDS("test", input) + # try() is necessary for Pandoc <= 2.14.2 + try(render(input, quiet = TRUE)) + expect_equal(readRDS(input), "test") +})