Skip to content

Commit e8f793b

Browse files
committed
Ensure we do not create C++ objects in unwind_protect
1 parent ccc89f0 commit e8f793b

File tree

5 files changed

+34
-19
lines changed

5 files changed

+34
-19
lines changed

inst/include/cpp11/doubles.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,22 @@ template <>
7979
inline r_vector<double>::r_vector(std::initializer_list<named_arg> il)
8080
: cpp11::r_vector<double>(safe[Rf_allocVector](REALSXP, il.size())),
8181
capacity_(il.size()) {
82+
protect_ = protect_sexp(data_);
83+
8284
try {
8385
unwind_protect([&] {
84-
protect_ = protect_sexp(data_);
8586
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
86-
sexp names(Rf_getAttrib(data_, R_NamesSymbol));
87+
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
8788
auto it = il.begin();
8889
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
89-
data_p_[i] = doubles(it->value())[0];
90+
data_p_[i] = REAL_ELT(it->value(), 0);
9091
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
9192
}
93+
UNPROTECT(1);
9294
});
9395
} catch (const unwind_exception& e) {
9496
release_protect(protect_);
97+
UNPROTECT(1);
9598
throw e;
9699
}
97100
}

inst/include/cpp11/integers.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,22 @@ template <>
9696
inline r_vector<int>::r_vector(std::initializer_list<named_arg> il)
9797
: cpp11::r_vector<int>(safe[Rf_allocVector](INTSXP, il.size())),
9898
capacity_(il.size()) {
99+
protect_ = protect_sexp(data_);
100+
99101
try {
100102
unwind_protect([&] {
101-
protect_ = protect_sexp(data_);
102-
attr("names") = Rf_allocVector(STRSXP, capacity_);
103-
sexp names(attr("names"));
103+
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
104+
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
104105
auto it = il.begin();
105106
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
106-
data_p_[i] = integers(it->value())[0];
107+
data_p_[i] = INTEGER_ELT(it->value(), 0);
107108
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
108109
}
110+
UNPROTECT(1);
109111
});
110112
} catch (const unwind_exception& e) {
111113
release_protect(protect_);
114+
UNPROTECT(1);
112115
throw e;
113116
}
114117
}

inst/include/cpp11/logicals.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,22 @@ template <>
8282
inline r_vector<Rboolean>::r_vector(std::initializer_list<named_arg> il)
8383
: cpp11::r_vector<Rboolean>(safe[Rf_allocVector](LGLSXP, il.size())),
8484
capacity_(il.size()) {
85+
protect_ = protect_sexp(data_);
86+
8587
try {
8688
unwind_protect([&] {
87-
protect_ = protect_sexp(data_);
88-
attr("names") = Rf_allocVector(STRSXP, capacity_);
89-
sexp names(attr("names"));
89+
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
90+
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
9091
auto it = il.begin();
9192
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
92-
data_p_[i] = logicals(it->value())[0];
93+
data_p_[i] = static_cast<Rboolean>(LOGICAL_ELT(it->value(), 0));
9394
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
9495
}
96+
UNPROTECT(1);
9597
});
9698
} catch (const unwind_exception& e) {
9799
release_protect(protect_);
100+
UNPROTECT(1);
98101
throw e;
99102
}
100103
}

inst/include/cpp11/raws.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,22 @@ template <>
8989
inline r_vector<uint8_t>::r_vector(std::initializer_list<named_arg> il)
9090
: cpp11::r_vector<uint8_t>(safe[Rf_allocVector](RAWSXP, il.size())),
9191
capacity_(il.size()) {
92+
protect_ = protect_sexp(data_);
93+
9294
try {
9395
unwind_protect([&] {
94-
protect_ = protect_sexp(data_);
95-
attr("names") = Rf_allocVector(STRSXP, capacity_);
96-
sexp names(attr("names"));
96+
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
97+
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
9798
auto it = il.begin();
9899
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
99-
data_p_[i] = cpp11::raws(it->value())[0];
100+
data_p_[i] = RAW_ELT(it->value(), 0);
100101
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
101102
}
103+
UNPROTECT(1);
102104
});
103105
} catch (const unwind_exception& e) {
104106
release_protect(protect_);
107+
UNPROTECT(1);
105108
throw e;
106109
}
107110
}

inst/include/cpp11/strings.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,19 +124,22 @@ template <>
124124
inline r_vector<r_string>::r_vector(std::initializer_list<named_arg> il)
125125
: cpp11::r_vector<r_string>(safe[Rf_allocVector](STRSXP, il.size())),
126126
capacity_(il.size()) {
127+
protect_ = protect_sexp(data_);
128+
127129
try {
128130
unwind_protect([&] {
129-
protect_ = protect_sexp(data_);
130-
attr("names") = Rf_allocVector(STRSXP, capacity_);
131-
sexp names(attr("names"));
131+
Rf_setAttrib(data_, R_NamesSymbol, Rf_allocVector(STRSXP, capacity_));
132+
SEXP names = PROTECT(Rf_getAttrib(data_, R_NamesSymbol));
132133
auto it = il.begin();
133134
for (R_xlen_t i = 0; i < capacity_; ++i, ++it) {
134-
SET_STRING_ELT(data_, i, strings(it->value())[0]);
135+
SET_STRING_ELT(data_, i, STRING_ELT(it->value(), 0));
135136
SET_STRING_ELT(names, i, Rf_mkCharCE(it->name(), CE_UTF8));
136137
}
138+
UNPROTECT(1);
137139
});
138140
} catch (const unwind_exception& e) {
139141
release_protect(protect_);
142+
UNPROTECT(1);
140143
throw e;
141144
}
142145
}

0 commit comments

Comments
 (0)