r-lib / cpp11

cpp11 helps you to interact with R objects using C++ code.
https://cpp11.r-lib.org/
Other
199 stars 46 forks source link

Nested `unwind_protect()` calls going through R can be very dangerous #326

Closed DavisVaughan closed 1 year ago

DavisVaughan commented 1 year ago

Assume you have cpp11 0.4.4 installed, with a "working" version of the cpp11_should_unwind_protect R global option ("working" in the sense that if you enter a nested unwind-protect call, then it notices that there is an outer unwind-protect present and decides not to unwind-protect its function too).

In this case, you can still have big problems with the following chain of events:

The big issue here is that A() and B() on their own can look very harmless, and like code that a package author would write without thinking twice about it.

I've come up with a reprex package to demonstrate this issue: https://github.com/DavisVaughan/testcpp11unwind


A few options:


The cpp11_should_unwind_protect nest guard is used for two things:

[[cpp11::register]]
void test() {
  cpp11::unwind_protect([&] {
    cpp11::unwind_protect([&] {
      Rf_error("oh no!");
    });
  });
}

If test() is called from R: