| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 457d244 commit 55b87c0
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -836,14 +836,17 @@ class ContextifyScript : public BaseObject { | |||
| 836 | 836 | ||
| 837 | 837 | Local<Value> result; | |
| 838 | 838 | bool timed_out = false; | |
| 839 | + bool received_signal = false; | ||
| 839 | 840 | if (break_on_sigint && timeout != -1) { | |
| 840 | 841 | Watchdog wd(env->isolate(), timeout); | |
| 841 | 842 | SigintWatchdog swd(env->isolate()); | |
| 842 | 843 | result = script->Run(); | |
| 843 | 844 | timed_out = wd.HasTimedOut(); | |
| 845 | + received_signal = swd.HasReceivedSignal(); | ||
| 844 | 846 | } else if (break_on_sigint) { | |
| 845 | 847 | SigintWatchdog swd(env->isolate()); | |
| 846 | 848 | result = script->Run(); | |
| 849 | + received_signal = swd.HasReceivedSignal(); | ||
| 847 | 850 | } else if (timeout != -1) { | |
| 848 | 851 | Watchdog wd(env->isolate(), timeout); | |
| 849 | 852 | result = script->Run(); | |
@@ -852,14 +855,26 @@ class ContextifyScript : public BaseObject { | |||
| 852 | 855 | result = script->Run(); | |
| 853 | 856 | } | |
| 854 | 857 | ||
| 855 | - if (try_catch.HasCaught() && try_catch.HasTerminated()) { | ||
| 856 | - env->isolate()->CancelTerminateExecution(); | ||
| 858 | + if (try_catch.HasCaught()) { | ||
| 859 | + if (try_catch.HasTerminated()) | ||
| 860 | + env->isolate()->CancelTerminateExecution(); | ||
| 861 | + | ||
| 862 | + // It is possible that execution was terminated by another timeout in | ||
| 863 | + // which this timeout is nested, so check whether one of the watchdogs | ||
| 864 | + // from this invocation is responsible for termination. | ||
| 857 | 865 | if (timed_out) { | |
| 858 | 866 | env->ThrowError("Script execution timed out."); | |
| 859 | - } else { | ||
| 867 | + } else if (received_signal) { | ||
| 860 | 868 | env->ThrowError("Script execution interrupted."); | |
| 861 | 869 | } | |
| 870 | + | ||
| 871 | + // If there was an exception thrown during script execution, re-throw it. | ||
| 872 | + // If one of the above checks threw, re-throw the exception instead of | ||
| 873 | + // letting try_catch catch it. | ||
| 874 | + // If execution has been terminated, but not by one of the watchdogs from | ||
| 875 | + // this invocation, this will re-throw a `null` value. | ||
| 862 | 876 | try_catch.ReThrow(); | |
| 877 | + | ||
| 863 | 878 | return false; | |
| 864 | 879 | } | |
| 865 | 880 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -99,7 +99,7 @@ void SigintWatchdog::Dispose() { | |||
| 99 | 99 | ||
| 100 | 100 | ||
| 101 | 101 | SigintWatchdog::SigintWatchdog(v8::Isolate* isolate) | |
| 102 | - : isolate_(isolate), destroyed_(false) { | ||
| 102 | + : isolate_(isolate), received_signal_(false), destroyed_(false) { | ||
| 103 | 103 | // Register this watchdog with the global SIGINT/Ctrl+C listener. | |
| 104 | 104 | SigintWatchdogHelper::GetInstance()->Register(this); | |
| 105 | 105 | // Start the helper thread, if that has not already happened. | |
@@ -120,6 +120,7 @@ void SigintWatchdog::Destroy() { | |||
| 120 | 120 | ||
| 121 | 121 | ||
| 122 | 122 | void SigintWatchdog::HandleSigint() { | |
| 123 | + received_signal_ = true; | ||
| 123 | 124 | isolate_->TerminateExecution(); | |
| 124 | 125 | } | |
| 125 | 126 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,11 +46,13 @@ class SigintWatchdog { | |||
| 46 | 46 | void Dispose(); | |
| 47 | 47 | ||
| 48 | 48 | v8::Isolate* isolate() { return isolate_; } | |
| 49 | + bool HasReceivedSignal() { return received_signal_; } | ||
| 49 | 50 | void HandleSigint(); | |
| 50 | 51 | private: | |
| 51 | 52 | void Destroy(); | |
| 52 | 53 | ||
| 53 | 54 | v8::Isolate* isolate_; | |
| 55 | + bool received_signal_; | ||
| 54 | 56 | bool destroyed_; | |
| 55 | 57 | }; | |
| 56 | 58 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -32,3 +32,26 @@ assert.throws(function() { | |||
| 32 | 32 | vm.runInNewContext('runInVM(10)', context, { timeout: 10000 }); | |
| 33 | 33 | throw new Error('Test 5 failed'); | |
| 34 | 34 | }, /Script execution timed out./); | |
| 35 | + | ||
| 36 | + // Test 6: Nested vm timeouts, outer timeout is shorter and fires first. | ||
| 37 | + assert.throws(function() { | ||
| 38 | + const context = { | ||
| 39 | + runInVM: function(timeout) { | ||
| 40 | + vm.runInNewContext('while(true) {}', context, { timeout: timeout }); | ||
| 41 | + } | ||
| 42 | + }; | ||
| 43 | + vm.runInNewContext('runInVM(10000)', context, { timeout: 100 }); | ||
| 44 | + throw new Error('Test 6 failed'); | ||
| 45 | + }, /Script execution timed out./); | ||
| 46 | + | ||
| 47 | + // Test 7: Nested vm timeouts, inner script throws an error. | ||
| 48 | + assert.throws(function() { | ||
| 49 | + const context = { | ||
| 50 | + runInVM: function(timeout) { | ||
| 51 | + vm.runInNewContext('throw new Error(\'foobar\')', context, { | ||
| 52 | + timeout: timeout | ||
| 53 | + }); | ||
| 54 | + } | ||
| 55 | + }; | ||
| 56 | + vm.runInNewContext('runInVM(10000)', context, { timeout: 100000 }); | ||
| 57 | + }, /foobar/); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments