Skip to content

Commit 860ef17

Browse files
Fixes for new rchk issues
1 parent dc39c97 commit 860ef17

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

src/assign.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ Moved out of ?setkey Details section in 1.12.2 (Mar 2019). Revisit this w.r.t. t
107107

108108
static int _selfrefok(SEXP x, Rboolean checkNames, Rboolean verbose) {
109109
SEXP v, p, tag, prot, names;
110-
v = getAttrib(x, SelfRefSymbol);
110+
int nprotect=0;
111+
v = PROTECT(getAttrib(x, SelfRefSymbol)); nprotect++;
111112
if (v==R_NilValue || TYPEOF(v)!=EXTPTRSXP) {
112113
// .internal.selfref missing is expected and normal for i) a pre v1.7.8 data.table loaded
113114
// from disk, and ii) every time a new data.table is over-allocated for the first time.
@@ -124,7 +125,7 @@ static int _selfrefok(SEXP x, Rboolean checkNames, Rboolean verbose) {
124125
if (!isNull(p)) error(_("Internal error: .internal.selfref ptr is neither NULL nor R_NilValue")); // # nocov
125126
tag = R_ExternalPtrTag(v);
126127
if (!(isNull(tag) || isString(tag))) error(_("Internal error: .internal.selfref tag is neither NULL nor a character vector")); // # nocov
127-
names = getAttrib(x, R_NamesSymbol);
128+
names = PROTECT(getAttrib(x, R_NamesSymbol)); nprotect++;
128129
if (names!=tag && isString(names) && !ALTREP(names)) // !ALTREP for #4734
129130
SET_TRUELENGTH(names, LENGTH(names));
130131
// R copied this vector not data.table; it's not actually over-allocated. It looks over-allocated
@@ -134,7 +135,9 @@ static int _selfrefok(SEXP x, Rboolean checkNames, Rboolean verbose) {
134135
return 0; // # nocov ; see http://stackoverflow.com/questions/15342227/getting-a-random-internal-selfref-error-in-data-table-for-r
135136
if (x!=R_ExternalPtrAddr(prot) && !ALTREP(x))
136137
SET_TRUELENGTH(x, LENGTH(x)); // R copied this vector not data.table, it's not actually over-allocated
137-
return checkNames ? names==tag : x==R_ExternalPtrAddr(prot);
138+
int ok = checkNames ? names==tag : x==R_ExternalPtrAddr(prot);
139+
UNPROTECT(nprotect);
140+
return ok;
138141
}
139142

140143
static Rboolean selfrefok(SEXP x, Rboolean verbose) { // for readability
@@ -221,7 +224,7 @@ SEXP setdt_nrows(SEXP x)
221224
if (Rf_inherits(xi, "POSIXlt")) {
222225
error(_("Column %d has class 'POSIXlt'. Please convert it to POSIXct (using as.POSIXct) and run setDT() again. We do not recommend the use of POSIXlt at all because it uses 40 bytes to store one date."), i+1);
223226
}
224-
SEXP dim_xi = getAttrib(xi, R_DimSymbol);
227+
SEXP dim_xi = PROTECT(getAttrib(xi, R_DimSymbol));
225228
R_len_t len_xi;
226229
R_len_t n_dim = LENGTH(dim_xi);
227230
if (n_dim) {
@@ -233,6 +236,7 @@ SEXP setdt_nrows(SEXP x)
233236
} else {
234237
len_xi = LENGTH(xi);
235238
}
239+
UNPROTECT(1);
236240
if (!base_length) {
237241
base_length = len_xi;
238242
} else if (len_xi != base_length) {

src/subset.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,9 @@ SEXP subsetDT(SEXP x, SEXP rows, SEXP cols) { // API change needs update NEWS.md
327327
SET_TRUELENGTH(tmp, LENGTH(tmp));
328328
SETLENGTH(tmp, LENGTH(cols));
329329
setAttrib(ans, R_NamesSymbol, tmp);
330-
subsetVectorRaw(tmp, getAttrib(x, R_NamesSymbol), cols, /*anyNA=*/false);
330+
SEXP x_names = PROTECT(getAttrib(x, R_NamesSymbol));
331+
subsetVectorRaw(tmp, x_names, cols, /*anyNA=*/false);
332+
UNPROTECT(1);
331333

332334
tmp = PROTECT(allocVector(INTSXP, 2)); nprotect++;
333335
INTEGER(tmp)[0] = NA_INTEGER;
@@ -339,7 +341,8 @@ SEXP subsetDT(SEXP x, SEXP rows, SEXP cols) { // API change needs update NEWS.md
339341
// but maintain key if ordered subset
340342
SEXP key = getAttrib(x, sym_sorted);
341343
if (length(key)) {
342-
SEXP in = PROTECT(chin(key, getAttrib(ans,R_NamesSymbol))); nprotect++;
344+
SEXP ans_names = PROTECT(getAttrib(ans, R_NamesSymbol)); nprotect++;
345+
SEXP in = PROTECT(chin(key, ans_names)); nprotect++;
343346
int i = 0; while(i<LENGTH(key) && LOGICAL(in)[i]) i++;
344347
// i is now the keylen that can be kept. 2 lines above much easier in C than R
345348
if (i==0 || !orderedSubset) {

0 commit comments

Comments
 (0)