Skip to content

Commit 4d42cdc

Browse files
add error to prevent segfault when setDT and attr<- (#6419)
* add error to prevent segfault * refine error msg Co-authored-by: Michael Chirico <[email protected]> * add tests * add issue to tests * add NEWS * fix wording Co-authored-by: Michael Chirico <[email protected]> --------- Co-authored-by: Michael Chirico <[email protected]> Co-authored-by: Michael Chirico <[email protected]>
1 parent 038ce2b commit 4d42cdc

File tree

3 files changed

+10
-0
lines changed

3 files changed

+10
-0
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ rowwiseDT(
6565

6666
9. `rbindlist` and `rbind` binding `bit64::integer64` columns with `character`/`complex`/`list` columns now works, [#5504](https://github.com/Rdatatable/data.table/issues/5504). Thanks to @MichaelChirico for the request and @ben-schwen for the PR.
6767

68+
10. Fixed possible segfault in `setDT(df); attr(df, key) <- value; set(df, ...)`, i.e. adding columns to an object with `set()` that was converted to data.table with `setDT()` and later had attributes add with `attr<-`, [#6410](https://github.com/Rdatatable/data.table/issues/6410). Thanks to @hongyuanjia for the report and @ben-schwen for the PR. Note that `setattr()` should be preferred for adding attributes to a data.table.
69+
6870
## NOTES
6971

7072
1. Tests run again when some Suggests packages are missing, [#6411](https://github.com/Rdatatable/data.table/issues/6411). Thanks @aadler for the note and @MichaelChirico for the fix.

inst/tests/tests.Rraw

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19240,3 +19240,9 @@ test(2290.2, DT[, `:=`(a := 2, c := 3)], error="It looks like you re-used `:=` i
1924019240
test(2290.3, DT[, `:=`(a, c := 3)], error="It looks like you re-used `:=` in argument 2")
1924119241
# partially-named `:=`(...) --> different branch, same error
1924219242
test(2290.4, DT[, `:=`(a = 2, c := 3)], error="It looks like you re-used `:=` in argument 2")
19243+
19244+
# segfault when selfref is not ok before set #6410
19245+
df = data.frame(a=1:3)
19246+
setDT(df)
19247+
attr(df, "att") = 1
19248+
test(2291.1, set(df, NULL, "new", "new"), error="attributes .* have been reassigned")

src/assign.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values)
529529
else if (TRUELENGTH(names) != oldtncol)
530530
// Use (long long) to cast R_xlen_t to a fixed type to robustly avoid -Wformat compiler warnings, see #5768, PRId64 didn't work
531531
internal_error(__func__, "selfrefnames is ok but tl names [%lld] != tl [%d]", (long long)TRUELENGTH(names), oldtncol); // # nocov
532+
if (!selfrefok(dt, verbose)) // #6410 setDT(dt) and subsequent attr<- can lead to invalid selfref
533+
error(_("It appears that at some earlier point, attributes of this data.table have been reassigned. Please use setattr(DT, name, value) rather than attr(DT, name) <- value. If that doesn't apply to you, please report your case to the data.table issue tracker."));
532534
SETLENGTH(dt, oldncol+LENGTH(newcolnames));
533535
SETLENGTH(names, oldncol+LENGTH(newcolnames));
534536
for (int i=0; i<LENGTH(newcolnames); ++i)

0 commit comments

Comments
 (0)