Skip to content

Commit 0171633

Browse files
committed
src: improve error handling in process.env handling
1 parent 2ff6c7e commit 0171633

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

src/node_env_var.cc

+39-20
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class RealEnvStore final : public KVStore {
4545
int32_t Query(Isolate* isolate, Local<String> key) const override;
4646
int32_t Query(const char* key) const override;
4747
void Delete(Isolate* isolate, Local<String> key) override;
48-
Local<Array> Enumerate(Isolate* isolate) const override;
48+
MaybeLocal<Array> Enumerate(Isolate* isolate) const override;
4949
};
5050

5151
class MapKVStore final : public KVStore {
@@ -56,7 +56,7 @@ class MapKVStore final : public KVStore {
5656
int32_t Query(Isolate* isolate, Local<String> key) const override;
5757
int32_t Query(const char* key) const override;
5858
void Delete(Isolate* isolate, Local<String> key) override;
59-
Local<Array> Enumerate(Isolate* isolate) const override;
59+
MaybeLocal<Array> Enumerate(Isolate* isolate) const override;
6060

6161
std::shared_ptr<KVStore> Clone(Isolate* isolate) const override;
6262

@@ -188,7 +188,7 @@ void RealEnvStore::Delete(Isolate* isolate, Local<String> property) {
188188
DateTimeConfigurationChangeNotification(isolate, key);
189189
}
190190

191-
Local<Array> RealEnvStore::Enumerate(Isolate* isolate) const {
191+
MaybeLocal<Array> RealEnvStore::Enumerate(Isolate* isolate) const {
192192
Mutex::ScopedLock lock(per_process::env_var_mutex);
193193
uv_env_item_t* items;
194194
int count;
@@ -203,12 +203,12 @@ Local<Array> RealEnvStore::Enumerate(Isolate* isolate) const {
203203
// If the key starts with '=' it is a hidden environment variable.
204204
if (items[i].name[0] == '=') continue;
205205
#endif
206-
MaybeLocal<String> str = String::NewFromUtf8(isolate, items[i].name);
207-
if (str.IsEmpty()) {
206+
Local<Value> str;
207+
if (!String::NewFromUtf8(isolate, items[i].name).ToLocal(&str)) {
208208
isolate->ThrowException(ERR_STRING_TOO_LONG(isolate));
209-
return Local<Array>();
209+
return {};
210210
}
211-
env_v[env_v_index++] = str.ToLocalChecked();
211+
env_v[env_v_index++] = str;
212212
}
213213

214214
return Array::New(isolate, env_v.out(), env_v_index);
@@ -219,14 +219,22 @@ std::shared_ptr<KVStore> KVStore::Clone(Isolate* isolate) const {
219219
Local<Context> context = isolate->GetCurrentContext();
220220

221221
std::shared_ptr<KVStore> copy = KVStore::CreateMapKVStore();
222-
Local<Array> keys = Enumerate(isolate);
222+
Local<Array> keys;
223+
if (!Enumerate(isolate).ToLocal(&keys)) {
224+
return nullptr;
225+
}
223226
uint32_t keys_length = keys->Length();
224227
for (uint32_t i = 0; i < keys_length; i++) {
225-
Local<Value> key = keys->Get(context, i).ToLocalChecked();
228+
Local<Value> key;
229+
Local<Value> value;
230+
if (!keys->Get(context, i).ToLocal(&key)) {
231+
return nullptr;
232+
}
226233
CHECK(key->IsString());
227-
copy->Set(isolate,
228-
key.As<String>(),
229-
Get(isolate, key.As<String>()).ToLocalChecked());
234+
if (!Get(isolate, key.As<String>()).ToLocal(&value)) {
235+
return nullptr;
236+
}
237+
copy->Set(isolate, key.As<String>(), value.As<String>());
230238
}
231239
return copy;
232240
}
@@ -272,15 +280,20 @@ void MapKVStore::Delete(Isolate* isolate, Local<String> key) {
272280
map_.erase(std::string(*str, str.length()));
273281
}
274282

275-
Local<Array> MapKVStore::Enumerate(Isolate* isolate) const {
283+
MaybeLocal<Array> MapKVStore::Enumerate(Isolate* isolate) const {
276284
Mutex::ScopedLock lock(mutex_);
277285
LocalVector<Value> values(isolate);
278286
values.reserve(map_.size());
279287
for (const auto& pair : map_) {
280-
values.emplace_back(
281-
String::NewFromUtf8(isolate, pair.first.data(),
282-
NewStringType::kNormal, pair.first.size())
283-
.ToLocalChecked());
288+
Local<Value> val;
289+
if (!String::NewFromUtf8(isolate,
290+
pair.first.data(),
291+
NewStringType::kNormal,
292+
pair.first.size())
293+
.ToLocal(&val)) {
294+
return {};
295+
}
296+
values.emplace_back(val);
284297
}
285298
return Array::New(isolate, values.data(), values.size());
286299
}
@@ -324,7 +337,10 @@ Maybe<void> KVStore::AssignToObject(v8::Isolate* isolate,
324337
v8::Local<v8::Context> context,
325338
v8::Local<v8::Object> object) {
326339
HandleScope scope(isolate);
327-
Local<Array> keys = Enumerate(isolate);
340+
Local<Array> keys;
341+
if (!Enumerate(isolate).ToLocal(&keys)) {
342+
return Nothing<void>();
343+
}
328344
uint32_t keys_length = keys->Length();
329345
for (uint32_t i = 0; i < keys_length; i++) {
330346
Local<Value> key;
@@ -421,6 +437,7 @@ static Intercepted EnvGetter(Local<Name> property,
421437
TraceEnvVar(env, "get", property.As<String>());
422438

423439
if (has_env) {
440+
// ToLocalChecked here is ok since we check IsEmpty above.
424441
info.GetReturnValue().Set(value_string.ToLocalChecked());
425442
return Intercepted::kYes;
426443
}
@@ -502,8 +519,10 @@ static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
502519

503520
TraceEnvVar(env, "enumerate environment variables");
504521

505-
info.GetReturnValue().Set(
506-
env->env_vars()->Enumerate(env->isolate()));
522+
Local<Array> ret;
523+
if (env->env_vars()->Enumerate(env->isolate()).ToLocal(&ret)) {
524+
info.GetReturnValue().Set(ret);
525+
}
507526
}
508527

509528
static Intercepted EnvDefiner(Local<Name> property,

src/node_worker.cc

+4
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,10 @@ void Worker::New(const FunctionCallbackInfo<Value>& args) {
545545
env_vars = env->env_vars();
546546
}
547547

548+
if (!env_vars) {
549+
THROW_ERR_OPERATION_FAILED(env, "Failed to copy environment variables");
550+
}
551+
548552
if (args[1]->IsObject() || args[2]->IsArray()) {
549553
per_isolate_opts.reset(new PerIsolateOptions());
550554

src/util.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ class KVStore {
315315
v8::Local<v8::String> key) const = 0;
316316
virtual int32_t Query(const char* key) const = 0;
317317
virtual void Delete(v8::Isolate* isolate, v8::Local<v8::String> key) = 0;
318-
virtual v8::Local<v8::Array> Enumerate(v8::Isolate* isolate) const = 0;
318+
virtual v8::MaybeLocal<v8::Array> Enumerate(v8::Isolate* isolate) const = 0;
319319

320320
virtual std::shared_ptr<KVStore> Clone(v8::Isolate* isolate) const;
321321
virtual v8::Maybe<void> AssignFromObject(v8::Local<v8::Context> context,

0 commit comments

Comments
 (0)