Skip to content

Commit ac4eefa

Browse files
fix: prevent global Promise overwrite for thread safety.
Proxy globalThis object in order to prevent JS user space code to override Promise global variable (e.g. mocha does that) aka our Promise Proxy which ensurses that Promises are resolved on the same thread on which they were created.
1 parent fd2703d commit ac4eefa

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

NativeScript/runtime/PromiseProxy.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#include "PromiseProxy.h"
2+
23
#include "Helpers.h"
34

45
using namespace v8;
56

67
namespace tns {
78

89
void PromiseProxy::Init(v8::Local<v8::Context> context) {
9-
std::string source = R"(
10+
std::string source = R"(
1011
// Ensure that Promise callbacks are executed on the
1112
// same thread on which they were created
1213
(() => {
@@ -72,18 +73,40 @@ void PromiseProxy::Init(v8::Local<v8::Context> context) {
7273
});
7374
}
7475
});
76+
globalThis = new Proxy(globalThis, {
77+
defineProperty: (target, prop, descriptor) => {
78+
if (prop === 'Promise') {
79+
return true;
80+
}
81+
return Object.defineProperty(target, prop, descriptor);
82+
},
83+
set: (target, prop, value, receiver) => {
84+
if (prop === 'Promise') {
85+
return true;
86+
}
87+
88+
const descriptor = Object.getOwnPropertyDescriptor(target, prop);
89+
if (descriptor && !descriptor.writable) {
90+
return false;
91+
}
92+
93+
target[prop] = value;
94+
return true;
95+
}
96+
});
7597
})();
7698
)";
7799

78-
Isolate* isolate = context->GetIsolate();
100+
Isolate* isolate = context->GetIsolate();
79101

80-
Local<Script> script;
81-
bool success = Script::Compile(context, tns::ToV8String(isolate, source)).ToLocal(&script);
82-
tns::Assert(success && !script.IsEmpty(), isolate);
102+
Local<Script> script;
103+
bool success = Script::Compile(context, tns::ToV8String(isolate, source))
104+
.ToLocal(&script);
105+
tns::Assert(success && !script.IsEmpty(), isolate);
83106

84-
Local<Value> result;
85-
success = script->Run(context).ToLocal(&result);
86-
tns::Assert(success, isolate);
107+
Local<Value> result;
108+
success = script->Run(context).ToLocal(&result);
109+
tns::Assert(success, isolate);
87110
}
88111

89-
}
112+
} // namespace tns

0 commit comments

Comments
 (0)