diff --git a/DESCRIPTION b/DESCRIPTION index 419f16a95b..745dbdf4ed 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -42,7 +42,8 @@ Authors@R: c( person("Roy","Storey", role="ctb"), person("Manish","Saraswat", role="ctb"), person("Morgan","Jacob", role="ctb"), - person("Michael","Schubmehl", role="ctb")) + person("Michael","Schubmehl", role="ctb"), + person("Davis","Vaughan", role="ctb")) Depends: R (>= 3.1.0) Imports: methods Suggests: bit64, curl, R.utils, knitr, xts, nanotime, zoo, yaml diff --git a/NEWS.md b/NEWS.md index f53b8fa6e7..d804f03125 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ ## BUG FIXES +1. `frollapply` could segfault and exceed R's C protect limits, [#3993](https://github.com/Rdatatable/data.table/issues/3993). Thanks to @DavisVaughan for reporting and fixing. + ## NOTES diff --git a/inst/tests/froll.Rraw b/inst/tests/froll.Rraw index 9cd95c72f1..62c16801ca 100644 --- a/inst/tests/froll.Rraw +++ b/inst/tests/froll.Rraw @@ -1027,6 +1027,12 @@ test(6010.005, frollmean(d, 3:4), frollapply(d, 3:4, mean)) d = rbind(d, list(NA,NA)) ans = list(c(NA,NA,1.5,2,1.5,2,2.5), c(NA,NA,NA,2,1,1.5,2), c(NA,NA,1.25,1.5,1.75,1.5,2), c(NA,NA,NA,1.5,1,1.25,1.5)) test(6010.006, frollapply(d, 3:4, function(x, ...) if (sum(x, ...)>5) min(x, ...) else max(x, ...), na.rm=TRUE), ans) +# segfault and protect limits #3993 - disabled by default due to high memory usage +if (FALSE) { + test(6010.007, frollapply(1, rep(1L, 1e5), identity), as.list(rep(1, 1e5))) + test(6010.008, frollapply(1, rep(1L, 1e6), identity), as.list(rep(1, 1e6))) + test(6010.009, frollapply(as.list(rep(1, 1e6)), 1, identity), as.list(rep(1, 1e6))) +} #### corner cases from examples test(6010.101, frollapply(1:5, 3, function(x) head(x, 2)), error="frollapply: results from provided FUN are not length 1") f = function(x) { diff --git a/src/frollR.c b/src/frollR.c index 66ac763c73..ceef97179c 100644 --- a/src/frollR.c +++ b/src/frollR.c @@ -296,8 +296,8 @@ SEXP frollapplyR(SEXP fun, SEXP obj, SEXP k, SEXP fill, SEXP align, SEXP rho) { if (verbose) Rprintf("%s: allocating memory for results %dx%d\n", __func__, nx, nk); ans_t *dans = (ans_t *)R_alloc(nx*nk, sizeof(ans_t)); - double* dx[nx]; - uint64_t inx[nx]; + double** dx = (double**)R_alloc(nx, sizeof(double*)); + uint64_t* inx = (uint64_t*)R_alloc(nx, sizeof(uint64_t)); for (R_len_t i=0; i