Skip to content

Commit 1742a31

Browse files
committed
Fix GCC sanitiser issue in df_list()
==2349903==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62500d7ca018 at pc 0x7f2671a13015 bp 0x7ffd56440d30 sp 0x7ffd56440d20 READ of size 8 at 0x62500d7ca018 thread T0 #0 0x7f2671a13014 in df_list_splice /data/gannet/ripley/R/packages/tests-gcc-SAN/vctrs/src/type-data-frame.c:300 #1 0x7f2671a13014 in df_list /data/gannet/ripley/R/packages/tests-gcc-SAN/vctrs/src/type-data-frame.c:246 #2 0x7f2671a1438e in data_frame /data/gannet/ripley/R/packages/tests-gcc-SAN/vctrs/src/type-data-frame.c:201 #3 0x7f2671a144fa in vctrs_data_frame /data/gannet/ripley/R/packages/tests-gcc-SAN/vctrs/src/type-data-frame.c:192
1 parent a672f8c commit 1742a31

File tree

4 files changed

+23
-16
lines changed

4 files changed

+23
-16
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: vctrs
22
Title: Vector Helpers
3-
Version: 0.3.3
3+
Version: 0.3.4
44
Authors@R:
55
c(person(given = "Hadley",
66
family = "Wickham",

NEWS.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11

2+
# vctrs 0.3.4
3+
4+
* Fixed a GCC sanitiser error revealed by CRAN checks.
5+
6+
27
# vctrs 0.3.3
38

49
* The `table` class is now implemented as a wrapper type that

src/type-data-frame.c

+16-14
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ SEXP vctrs_df_list(SEXP x, SEXP size, SEXP name_repair) {
223223
return out;
224224
}
225225

226-
static SEXP df_list_drop_null(SEXP x, r_ssize n);
227-
static SEXP df_list_splice(SEXP x, r_ssize n);
226+
static SEXP df_list_drop_null(SEXP x);
227+
static SEXP df_list_splice(SEXP x);
228228

229229
SEXP df_list(SEXP x, r_ssize size, const struct name_repair_opts* p_name_repair_opts) {
230230
if (TYPEOF(x) != VECSXP) {
@@ -242,8 +242,8 @@ SEXP df_list(SEXP x, r_ssize size, const struct name_repair_opts* p_name_repair_
242242
UNPROTECT(1);
243243
}
244244

245-
x = PROTECT(df_list_drop_null(x, n_cols));
246-
x = PROTECT(df_list_splice(x, n_cols));
245+
x = PROTECT(df_list_drop_null(x));
246+
x = PROTECT(df_list_splice(x));
247247

248248
SEXP names = PROTECT(r_names(x));
249249
names = PROTECT(vec_as_names(names, p_name_repair_opts));
@@ -253,10 +253,11 @@ SEXP df_list(SEXP x, r_ssize size, const struct name_repair_opts* p_name_repair_
253253
return x;
254254
}
255255

256-
static SEXP df_list_drop_null(SEXP x, r_ssize n) {
256+
static SEXP df_list_drop_null(SEXP x) {
257+
r_ssize n_cols = r_length(x);
257258
r_ssize count = 0;
258259

259-
for (r_ssize i = 0; i < n; ++i) {
260+
for (r_ssize i = 0; i < n_cols; ++i) {
260261
count += VECTOR_ELT(x, i) == R_NilValue;
261262
}
262263

@@ -267,12 +268,12 @@ static SEXP df_list_drop_null(SEXP x, r_ssize n) {
267268
SEXP names = PROTECT(r_names(x));
268269
const SEXP* p_names = STRING_PTR_RO(names);
269270

270-
r_ssize n_out = n - count;
271+
r_ssize n_out = n_cols - count;
271272
SEXP out = PROTECT(Rf_allocVector(VECSXP, n_out));
272273
SEXP out_names = PROTECT(Rf_allocVector(STRSXP, n_out));
273274
r_ssize out_i = 0;
274275

275-
for (r_ssize i = 0; i < n; ++i) {
276+
for (r_ssize i = 0; i < n_cols; ++i) {
276277
SEXP col = VECTOR_ELT(x, i);
277278

278279
if (col != R_NilValue) {
@@ -288,14 +289,15 @@ static SEXP df_list_drop_null(SEXP x, r_ssize n) {
288289
return out;
289290
}
290291

291-
static SEXP df_list_splice(SEXP x, r_ssize n) {
292+
static SEXP df_list_splice(SEXP x) {
292293
SEXP names = PROTECT(r_names(x));
293294
const SEXP* p_names = STRING_PTR_RO(names);
294295

295296
bool any_needs_splice = false;
297+
r_ssize n_cols = r_length(x);
296298
r_ssize i = 0;
297299

298-
for (; i < n; ++i) {
300+
for (; i < n_cols; ++i) {
299301
// Only splice unnamed data frames
300302
if (p_names[i] != strings_empty) {
301303
continue;
@@ -314,16 +316,16 @@ static SEXP df_list_splice(SEXP x, r_ssize n) {
314316
return x;
315317
}
316318

317-
SEXP splice = PROTECT(r_new_logical(n));
319+
SEXP splice = PROTECT(r_new_logical(n_cols));
318320
int* p_splice = LOGICAL(splice);
319321

320-
for (r_ssize j = 0; j < n; ++j) {
322+
for (r_ssize j = 0; j < n_cols; ++j) {
321323
p_splice[j] = 0;
322324
}
323325

324326
r_ssize width = i;
325327

326-
for (; i < n; ++i) {
328+
for (; i < n_cols; ++i) {
327329
// Only splice unnamed data frames
328330
if (p_names[i] != strings_empty) {
329331
++width;
@@ -346,7 +348,7 @@ static SEXP df_list_splice(SEXP x, r_ssize n) {
346348
r_ssize loc = 0;
347349

348350
// Splice loop
349-
for (r_ssize i = 0; i < n; ++i) {
351+
for (r_ssize i = 0; i < n_cols; ++i) {
350352
if (!p_splice[i]) {
351353
SET_VECTOR_ELT(out, loc, VECTOR_ELT(x, i));
352354
SET_STRING_ELT(out_names, loc, p_names[i]);

src/version.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#define R_NO_REMAP
22
#include <Rinternals.h>
33

4-
const char* vctrs_version = "0.3.3";
4+
const char* vctrs_version = "0.3.4";
55

66
/**
77
* This file records the expected package version in the shared

0 commit comments

Comments
 (0)