Skip to content

Commit 163fcec

Browse files
addaleaxtargos
authored andcommittedJun 14, 2021
src: fix multiple AddLinkedBinding() calls
Singly-linked lists are extended at their tail, not their head. This fixes using more than 2 linked addons at a time. PR-URL: #39012 Reviewed-By: Shelley Vohr <codebytere@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Richard Lau <rlau@redhat.com>
1 parent eb8f7ee commit 163fcec

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed
 

‎src/api/environment.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -671,10 +671,10 @@ void AddLinkedBinding(Environment* env, const node_module& mod) {
671671
CHECK_NOT_NULL(env);
672672
Mutex::ScopedLock lock(env->extra_linked_bindings_mutex());
673673

674-
node_module* prev_head = env->extra_linked_bindings_head();
674+
node_module* prev_tail = env->extra_linked_bindings_tail();
675675
env->extra_linked_bindings()->push_back(mod);
676-
if (prev_head != nullptr)
677-
prev_head->nm_link = &env->extra_linked_bindings()->back();
676+
if (prev_tail != nullptr)
677+
prev_tail->nm_link = &env->extra_linked_bindings()->back();
678678
}
679679

680680
void AddLinkedBinding(Environment* env, const napi_module& mod) {

‎src/env-inl.h

+5
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,11 @@ inline node_module* Environment::extra_linked_bindings_head() {
892892
&extra_linked_bindings_.front() : nullptr;
893893
}
894894

895+
inline node_module* Environment::extra_linked_bindings_tail() {
896+
return extra_linked_bindings_.size() > 0 ?
897+
&extra_linked_bindings_.back() : nullptr;
898+
}
899+
895900
inline const Mutex& Environment::extra_linked_bindings_mutex() const {
896901
return extra_linked_bindings_mutex_;
897902
}

‎src/env.h

+1
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,7 @@ class Environment : public MemoryRetainer {
10431043
inline void set_stopping(bool value);
10441044
inline std::list<node_module>* extra_linked_bindings();
10451045
inline node_module* extra_linked_bindings_head();
1046+
inline node_module* extra_linked_bindings_tail();
10461047
inline const Mutex& extra_linked_bindings_mutex() const;
10471048

10481049
inline bool filehandle_close_warning() const;

‎test/cctest/test_linked_binding.cc

+32
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,35 @@ TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingNapiInstanceDataTest) {
190190
CHECK_EQ(*instance_data, 1);
191191
delete instance_data;
192192
}
193+
194+
TEST_F(LinkedBindingTest, ManyBindingsTest) {
195+
const v8::HandleScope handle_scope(isolate_);
196+
const Argv argv;
197+
Env test_env {handle_scope, argv};
198+
199+
int calls = 0;
200+
AddLinkedBinding(*test_env, "local_linked1", InitializeLocalBinding, &calls);
201+
AddLinkedBinding(*test_env, "local_linked2", InitializeLocalBinding, &calls);
202+
AddLinkedBinding(*test_env, "local_linked3", InitializeLocalBinding, &calls);
203+
AddLinkedBinding(*test_env, local_linked_napi); // Add a N-API addon as well.
204+
AddLinkedBinding(*test_env, "local_linked4", InitializeLocalBinding, &calls);
205+
AddLinkedBinding(*test_env, "local_linked5", InitializeLocalBinding, &calls);
206+
207+
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
208+
209+
const char* run_script =
210+
"for (let i = 1; i <= 5; i++)process._linkedBinding(`local_linked${i}`);"
211+
"process._linkedBinding('local_linked_napi').hello";
212+
v8::Local<v8::Script> script = v8::Script::Compile(
213+
context,
214+
v8::String::NewFromOneByte(isolate_,
215+
reinterpret_cast<const uint8_t*>(run_script))
216+
.ToLocalChecked())
217+
.ToLocalChecked();
218+
v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked();
219+
v8::String::Utf8Value utf8val(isolate_, completion_value);
220+
CHECK_NOT_NULL(*utf8val);
221+
CHECK_EQ(strcmp(*utf8val, "world"), 0);
222+
CHECK_EQ(calls, 5);
223+
}
224+

0 commit comments

Comments
 (0)