@@ -107,7 +107,8 @@ Moved out of ?setkey Details section in 1.12.2 (Mar 2019). Revisit this w.r.t. t
107107
108108static 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
140143static 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 ) {
0 commit comments