1 /*
2  * RExec.cpp
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 
16 #define R_INTERNAL_FUNCTIONS
17 #include <r/RExec.hpp>
18 
19 #include <shared_core/FilePath.hpp>
20 #include <core/Log.hpp>
21 #include <core/StringUtils.hpp>
22 #include <core/system/Environment.hpp>
23 
24 #include <r/RErrorCategory.hpp>
25 #include <r/RSourceManager.hpp>
26 #include <r/RInterface.hpp>
27 #include <r/RCntxt.hpp>
28 #include <r/ROptions.hpp>
29 
30 #include <R_ext/Parse.h>
31 
32 #include <R_ext/libextern.h>
33 
34 extern "C" {
35 LibExtern Rboolean R_interrupts_suspended;
36 LibExtern int R_interrupts_pending;
37 #ifdef _WIN32
38 LibExtern int UserBreak;
39 #endif
40 }
41 
42 using namespace rstudio::core;
43 
44 namespace rstudio {
45 namespace r {
46 
47 namespace exec {
48 
49 namespace {
50 
51 bool s_wasInterrupted;
52 
53 MainThreadFunction s_mainThreadFunction;
54 
55 // create a scope for disabling any installed error handlers (e.g. recover)
56 // we need to do this so that recover isn't invoked while we are running
57 // R code within an r::exec scope -- when the user presses 0 to exit
58 // from recover and jump_to_top it gets eaten by the R_ToplevelExecute
59 // context so the console becomes unresponsive
60 class DisableErrorHandlerScope : boost::noncopyable
61 {
62 public:
DisableErrorHandlerScope()63    DisableErrorHandlerScope()
64       : didDisable_(false)
65    {
66       // allow users to enable / disable suppression of error handlers
67       // (primarily for debugging when behind-the-scenes R code emits an error
68       // that we'd like to learn a bit more about)
69       bool suppressed = r::options::getOption("rstudio.errors.suppressed", true, false);
70       if (!suppressed)
71          return;
72 
73       SEXP handlerSEXP = r::options::setErrorOption(R_NilValue);
74       if (handlerSEXP != R_NilValue)
75       {
76          preservedSEXP_.set(handlerSEXP);
77          didDisable_ = true;
78       }
79    }
~DisableErrorHandlerScope()80    virtual ~DisableErrorHandlerScope()
81    {
82       try
83       {
84          if (didDisable_)
85             r::options::setErrorOption(preservedSEXP_.get());
86       }
87       catch(...)
88       {
89       }
90    }
91 
92 private:
93    bool didDisable_;
94    r::sexp::PreservedSEXP preservedSEXP_;
95 };
96 
97 
parseString(const std::string & str,SEXP * pSEXP,sexp::Protect * pProtect)98 Error parseString(const std::string& str, SEXP* pSEXP, sexp::Protect* pProtect)
99 {
100    // string to parse
101    SEXP cv = sexp::create(str, pProtect);
102 
103    // do the parse and protect the result
104    ParseStatus ps;
105    *pSEXP=R_ParseVector(cv, 1, &ps, R_NilValue);
106    pProtect->add(*pSEXP);
107 
108    // check error/success
109    if (ps != PARSE_OK)
110    {
111       Error error(errc::ExpressionParsingError, ERROR_LOCATION);
112       error.addProperty("code", str);
113       return error;
114    }
115    else
116    {
117       return Success();
118    }
119 }
120 
121 
122 // evaluate expressions without altering the error handler (use with caution--
123 // a user-supplied error handler may be invoked if the expression raises
124 // an error!)
125 enum EvalType {
126    EvalTry,    // use R_tryEval
127    EvalDirect  // use Rf_eval directly
128 };
evaluateExpressionsUnsafe(SEXP expr,SEXP envir,SEXP * pSEXP,sexp::Protect * pProtect,EvalType evalType)129 Error evaluateExpressionsUnsafe(SEXP expr,
130                                 SEXP envir,
131                                 SEXP* pSEXP,
132                                 sexp::Protect* pProtect,
133                                 EvalType evalType)
134 {
135    // detect if an error occurred (only relevant for EvalTry)
136    int errorOccurred = 0;
137 
138    if (!isMainThread())
139    {
140       LOG_ERROR_MESSAGE("evaluateExpression called from thread other than main");
141       return rCodeExecutionError("Attempt to eval R on thread other than main", ERROR_LOCATION);
142    }
143 
144    // if we have an entire expression list, evaluate its contents one-by-one
145    // and return only the last one
146    if (TYPEOF(expr) == EXPRSXP)
147    {
148       DisableDebugScope disableStepInto(envir);
149 
150       for (int i = 0, n = LENGTH(expr); i < n; i++)
151       {
152          if (evalType == EvalTry)
153          {
154             SEXP result = R_tryEval(VECTOR_ELT(expr, i), envir, &errorOccurred);
155             if (errorOccurred == 0)
156                *pSEXP = result;
157          }
158          else
159          {
160             *pSEXP = Rf_eval(VECTOR_ELT(expr, i), envir);
161          }
162       }
163    }
164 
165    // otherwise, evaluate a single expression / call
166    else
167    {
168       DisableDebugScope disableStepInto(envir);
169 
170       if (evalType == EvalTry)
171       {
172          SEXP result = R_tryEval(expr, envir, &errorOccurred);
173          if (errorOccurred == 0)
174             *pSEXP = result;
175       }
176       else
177       {
178          *pSEXP = Rf_eval(expr, envir);
179       }
180    }
181 
182    // protect the result
183    pProtect->add(*pSEXP);
184 
185    if (errorOccurred)
186    {
187       // get error message -- note this results in a recursive call to
188       // evaluate expressions during the fetching of the error. if this
189       // call yielded an error then this could infinitely recurse. it doesn't
190       // appears as if geterrmessage will ever return an error state so
191       // this is likely not an issue. still, if we were concerned about it
192       // then we could simply read the error buffer directly from the module
193       // where do_geterrmessage is defined (errors.c)
194       return rCodeExecutionError(getErrorMessage(), ERROR_LOCATION);
195    }
196    else
197    {
198       return Success();
199    }
200 }
201 
evaluateExpressions(SEXP expr,SEXP env,SEXP * pSEXP,sexp::Protect * pProtect)202 Error evaluateExpressions(SEXP expr,
203                           SEXP env,
204                           SEXP* pSEXP,
205                           sexp::Protect* pProtect)
206 {
207    // disable custom error handlers while we execute code
208    DisableErrorHandlerScope disableErrorHandler;
209 
210    return evaluateExpressionsUnsafe(expr, env, pSEXP, pProtect, EvalTry);
211 }
212 
evaluateExpressions(SEXP expr,SEXP * pSEXP,sexp::Protect * pProtect)213 Error evaluateExpressions(SEXP expr, SEXP* pSEXP, sexp::Protect* pProtect)
214 {
215    return evaluateExpressions(expr, R_GlobalEnv, pSEXP, pProtect);
216 }
217 
topLevelExec(void * data)218 void topLevelExec(void *data)
219 {
220    boost::function<void()>* pFunction = (boost::function<void()>*)data;
221    pFunction->operator()();
222 }
223 
224 struct SEXPTopLevelExecContext
225 {
226    boost::function<SEXP()> function;
227    SEXP* pReturnSEXP;
228 };
229 
SEXPTopLevelExec(void * data)230 void SEXPTopLevelExec(void *data)
231 {
232    SEXPTopLevelExecContext* pContext = (SEXPTopLevelExecContext*)data;
233    *(pContext->pReturnSEXP) = pContext->function();
234 }
235 
236 } // anonymous namespace
237 
executeSafely(boost::function<void ()> function)238 Error executeSafely(boost::function<void()> function)
239 {
240    if (!isMainThread())
241    {
242       LOG_ERROR_MESSAGE("executeSafely called from thread other than main");
243       return rCodeExecutionError("execute function called from thread other than main", ERROR_LOCATION);
244    }
245    // disable custom error handlers while we execute code
246    DisableErrorHandlerScope disableErrorHandler;
247    DisableDebugScope disableStepInto(R_GlobalEnv);
248 
249    Rboolean success = R_ToplevelExec(topLevelExec, (void*)&function);
250    if (!success)
251    {
252       return rCodeExecutionError(getErrorMessage(), ERROR_LOCATION);
253    }
254    else
255    {
256       return Success();
257    }
258 }
259 
executeSafely(boost::function<SEXP ()> function,SEXP * pSEXP)260 core::Error executeSafely(boost::function<SEXP()> function, SEXP* pSEXP)
261 {
262    // disable custom error handlers while we execute code
263    DisableErrorHandlerScope disableErrorHandler;
264    DisableDebugScope disableStepInto(R_GlobalEnv);
265 
266    SEXPTopLevelExecContext context;
267    context.function = function;
268    context.pReturnSEXP = pSEXP;
269    Rboolean success = R_ToplevelExec(SEXPTopLevelExec, (void*)&context);
270    if (!success)
271    {
272       return rCodeExecutionError(getErrorMessage(), ERROR_LOCATION);
273    }
274    else
275    {
276       return Success();
277    }
278 }
279 
executeCallUnsafe(SEXP callSEXP,SEXP envirSEXP,SEXP * pResultSEXP,sexp::Protect * pProtect)280 Error executeCallUnsafe(SEXP callSEXP,
281                         SEXP envirSEXP,
282                         SEXP *pResultSEXP,
283                         sexp::Protect *pProtect)
284 {
285    return evaluateExpressionsUnsafe(callSEXP,
286                                     envirSEXP,
287                                     pResultSEXP,
288                                     pProtect,
289                                     EvalDirect);
290 }
291 
executeStringUnsafe(const std::string & str,SEXP envirSEXP,SEXP * pSEXP,sexp::Protect * pProtect)292 Error executeStringUnsafe(const std::string& str,
293                           SEXP envirSEXP,
294                           SEXP* pSEXP,
295                           sexp::Protect* pProtect)
296 {
297    SEXP parsedSEXP = R_NilValue;
298    Error error = r::exec::parseString(str, &parsedSEXP, pProtect);
299    if (error)
300       return error;
301 
302    return evaluateExpressionsUnsafe(parsedSEXP, envirSEXP, pSEXP, pProtect, EvalDirect);
303 }
304 
executeStringUnsafe(const std::string & str,SEXP * pSEXP,sexp::Protect * pProtect)305 Error executeStringUnsafe(const std::string& str,
306                           SEXP* pSEXP,
307                           sexp::Protect* pProtect)
308 {
309    return executeStringUnsafe(str, R_GlobalEnv, pSEXP, pProtect);
310 }
311 
executeString(const std::string & str)312 Error executeString(const std::string& str)
313 {
314    sexp::Protect rProtect;
315    SEXP ignoredSEXP;
316    return evaluateString(str, &ignoredSEXP, &rProtect);
317 }
318 
evaluateString(const std::string & str,SEXP * pSEXP,sexp::Protect * pProtect,EvalFlags flags)319 Error evaluateString(const std::string& str,
320                      SEXP* pSEXP,
321                      sexp::Protect* pProtect,
322                      EvalFlags flags)
323 {
324    if (!isMainThread())
325    {
326       LOG_ERROR_MESSAGE("evaluateString called from thread other than main: " + str);
327       return rCodeExecutionError("Attempt to eval R off of main thread", ERROR_LOCATION);
328    }
329    // refresh source if necessary (no-op in production)
330    r::sourceManager().reloadIfNecessary();
331 
332    // surround the string with try in silent mode so we can capture error text
333    std::string rCode = "base::try(" + str + ", silent = TRUE)";
334 
335    // suppress warnings if requested
336    if (flags & EvalFlagsSuppressWarnings)
337       rCode = "base::suppressWarnings(" + rCode + ")";
338 
339    if (flags & EvalFlagsSuppressMessages)
340       rCode = "base::suppressMessages(" + rCode + ")";
341 
342    // parse expression
343    SEXP ps;
344    Error parseError = parseString(rCode, &ps, pProtect);
345    if (parseError)
346       return parseError;
347 
348    // evaluate the expression
349    Error evalError = evaluateExpressions(ps, pSEXP, pProtect);
350    if (evalError)
351    {
352       evalError.addProperty("code", str);
353       return evalError;
354    }
355 
356    // check for try-error
357    if (Rf_inherits(*pSEXP, "try-error"))
358    {
359       // get error message (merely log on failure so we can continue
360       // and return the real error)
361       std::string errorMsg;
362       Error extractError = sexp::extract(*pSEXP, &errorMsg);
363       if (extractError)
364          LOG_ERROR(extractError);
365 
366       // add it to the error
367       return rCodeExecutionError(errorMsg, ERROR_LOCATION);
368    }
369 
370    return Success();
371 }
372 
atTopLevelContext()373 bool atTopLevelContext()
374 {
375    return context::RCntxt::begin()->callflag() == CTXT_TOPLEVEL;
376 }
377 
378 // Returns true for all threads unless initMainThread was called from the main one
isMainThread()379 bool isMainThread()
380 {
381    if (!s_mainThreadFunction)
382       return true; // Not determined
383    return s_mainThreadFunction();
384 }
385 
386 // Call this from the main thread to enable main-thread diagnostic checks.
initMainThread(MainThreadFunction fun)387 void initMainThread(MainThreadFunction fun)
388 {
389    s_mainThreadFunction = fun;
390 }
391 
RFunction(SEXP functionSEXP)392 RFunction::RFunction(SEXP functionSEXP)
393 {
394    functionSEXP_ = functionSEXP;
395    preserver_.add(functionSEXP_);
396 }
397 
~RFunction()398 RFunction::~RFunction()
399 {
400 }
401 
commonInit(const std::string & functionName)402 void RFunction::commonInit(const std::string& functionName)
403 {
404    // refresh source if necessary (no-op in production)
405    r::sourceManager().reloadIfNecessary();
406 
407    // record functionName (used later for diagnostics)
408    functionName_ = functionName;
409 
410    // handle empty function names up front
411    if (functionName.empty())
412    {
413       functionSEXP_ = R_UnboundValue;
414       return;
415    }
416 
417    // otherwise, build call to function
418    // check for namespace qualifier and handle that if set
419    auto pos = functionName.find(":::");
420    if (pos == std::string::npos)
421    {
422       functionSEXP_ = Rf_install(functionName.c_str());
423    }
424    else
425    {
426       functionSEXP_ = Rf_lang3(
427                Rf_install(":::"),
428                Rf_install(functionName.substr(0, pos).c_str()),
429                Rf_install(functionName.substr(pos + 3).c_str()));
430       preserver_.add(functionSEXP_);
431    }
432 }
433 
callUnsafe()434 Error RFunction::callUnsafe()
435 {
436    return call(R_GlobalEnv, false);
437 }
438 
call(SEXP evalNS,bool safely)439 Error RFunction::call(SEXP evalNS, bool safely)
440 {
441    sexp::Protect rProtect;
442    SEXP ignoredResultSEXP;
443    return call(evalNS, safely, &ignoredResultSEXP, &rProtect);
444 }
445 
call(SEXP * pResultSEXP,sexp::Protect * pProtect)446 Error RFunction::call(SEXP* pResultSEXP, sexp::Protect* pProtect)
447 {
448    return call(R_GlobalEnv, pResultSEXP, pProtect);
449 }
450 
call(SEXP evalNS,SEXP * pResultSEXP,sexp::Protect * pProtect)451 Error RFunction::call(SEXP evalNS, SEXP* pResultSEXP, sexp::Protect* pProtect)
452 {
453    return call(evalNS, true, pResultSEXP, pProtect);
454 }
455 
call(SEXP evalNS,bool safely,SEXP * pResultSEXP,sexp::Protect * pProtect)456 Error RFunction::call(SEXP evalNS,
457                       bool safely,
458                       SEXP* pResultSEXP,
459                       sexp::Protect* pProtect)
460 {
461    // check that the function exists
462    if (functionSEXP_ != R_UnboundValue)
463    {
464       Error existsError = safely ?
465                evaluateExpressions(functionSEXP_, evalNS, pResultSEXP, pProtect) :
466                evaluateExpressionsUnsafe(functionSEXP_, evalNS, pResultSEXP, pProtect, EvalTry);
467 
468       if (existsError)
469          functionSEXP_ = R_UnboundValue;
470    }
471 
472    // verify the function
473    if (functionSEXP_ == R_UnboundValue)
474    {
475       Error error(errc::SymbolNotFoundError, ERROR_LOCATION);
476       if (!functionName_.empty())
477          error.addProperty("symbol", functionName_);
478       return error;
479    }
480 
481    if (!isMainThread())
482    {
483       LOG_ERROR_MESSAGE("Attempt to call R function: " + functionName_ + " on thread other than main");
484       return rCodeExecutionError("Attempt to call R function on thread other than main", ERROR_LOCATION);
485    }
486 
487    // create the call object (LANGSXP) with the correct number of elements
488    SEXP callSEXP;
489    pProtect->add(callSEXP = Rf_allocVector(LANGSXP, 1 + params_.size()));
490    SET_TAG(callSEXP, R_NilValue); // just like do_ascall() does
491 
492    // assign the function to the first element of the call
493    SETCAR(callSEXP, functionSEXP_);
494 
495    // assign parameters to the subseqent elements of the call
496    SEXP nextSlotSEXP = CDR(callSEXP);
497    for (std::vector<Param>::const_iterator
498             it = params_.begin(); it != params_.end(); ++it)
499    {
500       SETCAR(nextSlotSEXP, it->valueSEXP);
501       // parameters can optionally be named
502       if (!(it->name.empty()))
503          SET_TAG(nextSlotSEXP, Rf_install(it->name.c_str()));
504       nextSlotSEXP = CDR(nextSlotSEXP);
505    }
506 
507    // call the function
508    Error error = safely ?
509             evaluateExpressions(callSEXP, evalNS, pResultSEXP, pProtect) :
510             evaluateExpressionsUnsafe(callSEXP, evalNS, pResultSEXP, pProtect,
511                   EvalTry);
512    if (error)
513       return error;
514 
515    // return success
516    return Success();
517 }
518 
rBinaryPath()519 FilePath rBinaryPath()
520 {
521    FilePath binPath = FilePath(R_HomeDir()).completePath("bin");
522 #ifdef _WIN32
523    return binPath.completePath("Rterm.exe");
524 #else
525    return binPath.completePath("R");
526 #endif
527 }
528 
system(const std::string & command,std::string * pOutput)529 Error system(const std::string& command, std::string* pOutput)
530 {
531    r::exec::RFunction system("system", command);
532    system.addParam("intern", true);
533    system.addParam("ignore.stderr", true);
534 
535    // call it
536    Error error = system.call(pOutput);
537    if (error)
538    {
539       // if it is NoDataAvailable this means empty output
540       if (error == r::errc::NoDataAvailableError)
541       {
542          pOutput->clear();
543          return Success();
544       }
545       else
546       {
547          return error;
548       }
549    }
550    else
551    {
552       return Success();
553    }
554 }
555 
556 
error(const std::string & message)557 void error(const std::string& message)
558 {
559    Rf_error("%s", message.c_str());
560 }
561 
errorCall(SEXP call,const std::string & message)562 void errorCall(SEXP call, const std::string& message)
563 {
564    Rf_errorcall(call, "%s", message.c_str());
565 }
566 
getErrorMessage()567 std::string getErrorMessage()
568 {
569    return R_curErrorBuf();
570 }
571 
572 
warning(const std::string & warning)573 void warning(const std::string& warning)
574 {
575    Rf_warning("%s", warning.c_str());
576 }
577 
message(const std::string & message)578 void message(const std::string& message)
579 {
580    Error error = r::exec::RFunction("message", message).call();
581    if (error)
582       LOG_ERROR(error);
583 }
584 
interruptsPending()585 bool interruptsPending()
586 {
587 #ifdef _WIN32
588    return UserBreak == 1 ? true : false;
589 #else
590    return R_interrupts_pending == 1 ? true : false;
591 #endif
592 }
593 
setInterruptsPending(bool pending)594 void setInterruptsPending(bool pending)
595 {
596    setWasInterrupted(pending);
597 
598 #ifdef _WIN32
599    UserBreak = pending ? 1 : 0;
600 #else
601    R_interrupts_pending = pending ? 1 : 0;
602 #endif
603 }
604 
checkUserInterrupt()605 void checkUserInterrupt()
606 {
607    R_CheckUserInterrupt();
608 }
609 
IgnoreInterruptsScope()610 IgnoreInterruptsScope::IgnoreInterruptsScope()
611    : pSignalBlocker_(new core::system::SignalBlocker())
612 {
613    // save suspend state and set suspend flag
614    previousInterruptsSuspended_ = (R_interrupts_suspended == TRUE);
615    R_interrupts_suspended = TRUE;
616 
617    // clear existing
618    setInterruptsPending(false);
619 
620    // enable signal blocker
621    Error error = pSignalBlocker_->block(core::system::SigInt);
622    if (error)
623       LOG_ERROR(error);
624 }
625 
~IgnoreInterruptsScope()626 IgnoreInterruptsScope::~IgnoreInterruptsScope()
627 {
628    try
629    {
630       // delete signal blocker (may cause delivery of one of the blocked
631       // interrupts, but we restore the previous interrupt state below
632       // so this is no problem)
633       pSignalBlocker_.reset();
634 
635       // restore suspended state
636       R_interrupts_suspended = previousInterruptsSuspended_ ? TRUE : FALSE;
637 
638       // clear state
639       setInterruptsPending(false);
640    }
641    catch(...)
642    {
643    }
644 }
645 
DisableDebugScope(SEXP env)646 DisableDebugScope::DisableDebugScope(SEXP env)
647    : rdebug_(0),
648      env_(nullptr)
649 {
650    // nothing to do if no environment
651    if (env == nullptr)
652       return;
653 
654    // check to see whether there's a debug flag set on this environment
655    rdebug_ = RDEBUG(env);
656 
657    // if there is, turn it off and save the old flag for restoration
658    if (rdebug_ != 0)
659    {
660       SET_RDEBUG(env, 0);
661       env_ = env;
662    }
663 }
664 
~DisableDebugScope()665 DisableDebugScope::~DisableDebugScope()
666 {
667    // if we disabled debugging and debugging didn't end during the command
668    // evaluation, restore debugging
669    if (env_ != nullptr && !atTopLevelContext())
670    {
671       SET_RDEBUG(env_, rdebug_);
672    }
673 }
674 
getWasInterrupted()675 bool getWasInterrupted()
676 {
677    return s_wasInterrupted;
678 }
679 
setWasInterrupted(bool wasInterrupted)680 void setWasInterrupted(bool wasInterrupted)
681 {
682    s_wasInterrupted = wasInterrupted;
683 }
684 
685 } // namespace exec
686 } // namespace r
687 } // namespace rstudio
688 
689 
690 
691