From 546de995beb7c95a07daaccd2e60f75087a6a144 Mon Sep 17 00:00:00 2001 From: AmanKashyap0807 Date: Tue, 10 Feb 2026 03:20:17 +0530 Subject: [PATCH 1/2] Fix fread clipboard handling on Windows (fixes #1292) --- NEWS.md | 2 ++ R/fread.R | 23 +++++++++++++++++++++++ inst/tests/tests.Rraw | 8 ++++++++ 3 files changed, 33 insertions(+) diff --git a/NEWS.md b/NEWS.md index fd0ee8bf1..774527c71 100644 --- a/NEWS.md +++ b/NEWS.md @@ -38,6 +38,8 @@ 4. `rowwiseDT()` now provides a helpful error message when a complex object that is not a list (e.g., a function) is provided as a cell value, instructing the user to wrap it in `list()`, [#7219](https://github.com/Rdatatable/data.table/issues/7219). Thanks @kylebutts for the report and @venom1204 for the fix. +5. `fread()` now recognizes Windows clipboard tokens such as `clipboard`, avoiding shell execution failures, [#1292](https://github.com/Rdatatable/data.table/issues/1292). Thanks @mbacou for the report and @AmanKashyap0807 for the fix. + ### Notes 1. {data.table} now depends on R 3.5.0 (2018). diff --git a/R/fread.R b/R/fread.R index bc8509c71..f5a7ae5c4 100644 --- a/R/fread.R +++ b/R/fread.R @@ -63,6 +63,29 @@ yaml=FALSE, tmpdir=tempdir(), tz="UTC") # input is data itself containing at least one \n or \r } else if (startsWith(input, " ")) { stopf("input= contains no \\n or \\r, but starts with a space. Please remove the leading space, or use text=, file= or cmd=") + } else if (grepl("^clipboard(-[0-9]+)?$", tolower(input))) { + is_windows = identical(.Platform$OS.type, "windows") + if (is_windows) { + clip = tryCatch(utils::readClipboard(), error = identity) + # for errors due to permissions, clipboard locked or system errors + if (inherits(clip, "error")) { + stopf("Reading clipboard failed on Windows: %s", conditionMessage(clip)) + } + if (!length(clip) || all(!nzchar(trimws(clip)))) { + stopf("Clipboard is empty.") + } + tmpFile = tempfile(tmpdir=tmpdir) + on.exit(unlink(tmpFile), add=TRUE) + tryCatch({ + writeLines(paste(clip, collapse="\n"), tmpFile, useBytes=TRUE) + file = tmpFile + }, error = function(e) { + stopf("Writing clipboard to temporary file failed: %s. Check tmpdir=%s.", conditionMessage(e), tmpdir) + }) + } else { + # Note: macOS (pbpaste) and Linux (xclip/xsel) support discussed in #1292 + stopf("Clipboard reading is supported on Windows only.") + } } else if (length(grep(' ', input, fixed=TRUE)) && !file.exists(gsub("^file://", "", input))) { # file name or path containing spaces is not a command. file.exists() doesn't understand file:// (#7550) cmd = input if (input_has_vars && getOption("datatable.fread.input.cmd.message", TRUE)) { diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index f30467dae..18c72e155 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21515,3 +21515,11 @@ test(2365.1, melt(df_melt, id.vars=1:2), melt(dt_melt, id.vars=1:2)) df_dcast = data.frame(a = c("x", "y"), b = 1:2, v = 3:4) dt_dcast = data.table(a = c("x", "y"), b = 1:2, v = 3:4) test(2365.2, dcast(df_dcast, a ~ b, value.var = "v"), dcast(dt_dcast, a ~ b, value.var = "v")) + +# Test fread clipboard input on Windows (issue #1292) +if (.Platform$OS.type == "windows") local({ + temp <- c("a\tb", "1\t2") + utils::writeClipboard(temp) + on.exit(utils::writeClipboard(""), add = TRUE) + test(2366, fread("clipboard-128"), data.table(a = 1L, b = 2L)) +}) \ No newline at end of file From c68136d0f3b9e745305cb479d6ba5bf0c94126b9 Mon Sep 17 00:00:00 2001 From: AmanKashyap0807 Date: Tue, 10 Feb 2026 04:21:45 +0530 Subject: [PATCH 2/2] addressing linting --- R/fread.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/fread.R b/R/fread.R index f5a7ae5c4..fe40a240c 100644 --- a/R/fread.R +++ b/R/fread.R @@ -67,11 +67,11 @@ yaml=FALSE, tmpdir=tempdir(), tz="UTC") is_windows = identical(.Platform$OS.type, "windows") if (is_windows) { clip = tryCatch(utils::readClipboard(), error = identity) - # for errors due to permissions, clipboard locked or system errors + # for errors due to permissions, clipboard locked or system errors if (inherits(clip, "error")) { stopf("Reading clipboard failed on Windows: %s", conditionMessage(clip)) } - if (!length(clip) || all(!nzchar(trimws(clip)))) { + if (!length(clip) || !all(nzchar(trimws(clip)))) { stopf("Clipboard is empty.") } tmpFile = tempfile(tmpdir=tmpdir)