Skip to content

Commit 2642b84

Browse files
authored
Avoid memcpy(dst, NULL, 0) in forder.c (#7055)
* flush(): avoid memcpy(<dst>, NULL, 0) During thread contention, it's possible for a thread to not call push() even once, leaving gs_thread[me] unallocated. The resulting call to memcpy() was noticed by a sanitizer during additional CRAN checks. * NEWS item * Add nocov to the hard-to-test branch Currently, the condition is only encountered during thread contention, which is prohibitively expensive to test or at least requires non-portable tricks. * Explain why the branch is #nocov
1 parent fb419f1 commit 2642b84

File tree

2 files changed

+4
-0
lines changed

2 files changed

+4
-0
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838

3939
9. Joins to extended data.frames, e.g. `x[i, col := x.col1 + i.col2]` where `i` is a `tbl`, can use the `x.` and `i.` prefix forms, [#6998](https://github.com/Rdatatable/data.table/issues/6998). Thanks @MichaelChirico for the bug and PR.
4040

41+
10. On a heavily loaded machine, a `forder` thread could try to perform a zero-length copy from a null pointer, which was de-facto harmless but is against the C standard and was caught by additional CRAN checks, [#7051](https://github.com/Rdatatable/data.table/issues/7051). Thanks to @helske for the report and @aitap for the PR.
42+
4143
### NOTES
4244

4345
1. Continued work to remove non-API C functions, [#6180](https://github.com/Rdatatable/data.table/issues/6180). Thanks Ivan Krylov for the PRs and for writing a clear and concise guide about the R API: https://aitap.codeberg.page/R-api/.

src/forder.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ static void flush(void) {
128128
if (!retgrp) return;
129129
int me = omp_get_thread_num();
130130
int n = gs_thread_n[me];
131+
// normally doesn't happen, can be encountered under heavy load, #7051
132+
if (!n) return; // # nocov
131133
int newn = gs_n + n;
132134
if (gs_alloc < newn) {
133135
gs_alloc = (newn < nrow/3) ? (1+(newn*2)/4096)*4096 : nrow;

0 commit comments

Comments
 (0)