diff --git a/NEWS.md b/NEWS.md index 5e04807fbc..94f52f7a3f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -120,6 +120,8 @@ 15. `rbind` and `rbindlist` of zero-row items now retain (again) the unused levels of any (zero-length) factor columns, [#3508](https://github.com/Rdatatable/data.table/issues/3508). This was a regression in v1.12.2 just for zero-row items. Unused factor levels were already retained for items having `nrow>=1`. Thanks to Gregory Demin for reporting. +16. `rbind` and `rbindlist` of an item containing an ordered factor with levels containing an `NA` (as opposed to an NA integer) could segfault, [#3601](https://github.com/Rdatatable/data.table/issues/3601). This was a a regression in v1.12.2. Thanks to Damian Betebenner for reporting. + #### NOTES 1. `rbindlist`'s `use.names="check"` now emits its message for automatic column names (`"V[0-9]+"`) too, [#3484](https://github.com/Rdatatable/data.table/pull/3484). See news item 5 of v1.12.2 below. diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 97c0de9751..d5e98d0c87 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -14922,6 +14922,16 @@ test(2051.5, as.POSIXct(t, structure(0L, class="Date")), .POSIXct(0, 'UTC')) DT = data.table(a = 1:3) test(2051.6, DT[order(sin(a/pi))], DT) +# rbindlist ordered factor with an NA level, #3601 +dt1 = structure(list(V1 = c("2016", "2016", "2016", "2016", "2016"), + V46 = structure(c(3L, 1L, 1L, NA, 3L), .Label = c("Low", + "Typical", "High", NA), class = c("ordered", "factor"))), class = c("data.table", "data.frame"), row.names = c(NA, -5L)) +dt2 = structure(list(V1 = c("2018", "2018", "2018", "2018", "2018")), row.names = c(NA, -5L), class = c("data.table", "data.frame")) +test(2052, rbindlist(list(dt1, dt2), fill=TRUE), + data.table(V1=c(dt1$V1, dt2$V1), + V46=structure(c(3L,1L,1L,NA,3L,NA,NA,NA,NA,NA), .Label=c("Low","Typical","High",NA), class = c("ordered", "factor")))) + + ################################### # Add new tests above this line # ################################### diff --git a/src/rbindlist.c b/src/rbindlist.c index 1a0cffae31..dae2630917 100644 --- a/src/rbindlist.c +++ b/src/rbindlist.c @@ -351,7 +351,6 @@ SEXP rbindlist(SEXP l, SEXP usenamesArg, SEXP fillArg, SEXP idcolArg) if (!levelsRaw) { savetl_end(); error("Failed to allocate working memory for %d ordered factor levels of result column %d", nLevel, idcol+j+1); } for (int k=0; k0) savetl(s); levelsRaw[k] = s; SET_TRUELENGTH(s,-k-1);