Skip to content

Commit 56380df

Browse files
jasnellRafaelGSS
authored andcommitted
src: improve error handling in process.env handling
PR-URL: #57707 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent db8b29d commit 56380df

File tree

3 files changed

+52
-26
lines changed

3 files changed

+52
-26
lines changed

src/node_env_var.cc

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ using v8::Maybe;
2626
using v8::MaybeLocal;
2727
using v8::Name;
2828
using v8::NamedPropertyHandlerConfiguration;
29-
using v8::NewStringType;
3029
using v8::Nothing;
3130
using v8::Object;
3231
using v8::ObjectTemplate;
@@ -45,7 +44,7 @@ class RealEnvStore final : public KVStore {
4544
int32_t Query(Isolate* isolate, Local<String> key) const override;
4645
int32_t Query(const char* key) const override;
4746
void Delete(Isolate* isolate, Local<String> key) override;
48-
Local<Array> Enumerate(Isolate* isolate) const override;
47+
MaybeLocal<Array> Enumerate(Isolate* isolate) const override;
4948
};
5049

5150
class MapKVStore final : public KVStore {
@@ -56,7 +55,7 @@ class MapKVStore final : public KVStore {
5655
int32_t Query(Isolate* isolate, Local<String> key) const override;
5756
int32_t Query(const char* key) const override;
5857
void Delete(Isolate* isolate, Local<String> key) override;
59-
Local<Array> Enumerate(Isolate* isolate) const override;
58+
MaybeLocal<Array> Enumerate(Isolate* isolate) const override;
6059

6160
std::shared_ptr<KVStore> Clone(Isolate* isolate) const override;
6261

@@ -131,8 +130,12 @@ MaybeLocal<String> RealEnvStore::Get(Isolate* isolate,
131130

132131
if (value.has_value()) {
133132
std::string val = value.value();
134-
return String::NewFromUtf8(
135-
isolate, val.data(), NewStringType::kNormal, val.size());
133+
Local<Value> ret;
134+
if (!ToV8Value(isolate->GetCurrentContext(), val).ToLocal(&ret)) {
135+
return {};
136+
}
137+
DCHECK(ret->IsString());
138+
return ret.As<String>();
136139
}
137140

138141
return MaybeLocal<String>();
@@ -188,7 +191,7 @@ void RealEnvStore::Delete(Isolate* isolate, Local<String> property) {
188191
DateTimeConfigurationChangeNotification(isolate, key);
189192
}
190193

191-
Local<Array> RealEnvStore::Enumerate(Isolate* isolate) const {
194+
MaybeLocal<Array> RealEnvStore::Enumerate(Isolate* isolate) const {
192195
Mutex::ScopedLock lock(per_process::env_var_mutex);
193196
uv_env_item_t* items;
194197
int count;
@@ -203,12 +206,12 @@ Local<Array> RealEnvStore::Enumerate(Isolate* isolate) const {
203206
// If the key starts with '=' it is a hidden environment variable.
204207
if (items[i].name[0] == '=') continue;
205208
#endif
206-
MaybeLocal<String> str = String::NewFromUtf8(isolate, items[i].name);
207-
if (str.IsEmpty()) {
209+
Local<Value> str;
210+
if (!String::NewFromUtf8(isolate, items[i].name).ToLocal(&str)) {
208211
isolate->ThrowException(ERR_STRING_TOO_LONG(isolate));
209-
return Local<Array>();
212+
return {};
210213
}
211-
env_v[env_v_index++] = str.ToLocalChecked();
214+
env_v[env_v_index++] = str;
212215
}
213216

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

221224
std::shared_ptr<KVStore> copy = KVStore::CreateMapKVStore();
222-
Local<Array> keys = Enumerate(isolate);
225+
Local<Array> keys;
226+
if (!Enumerate(isolate).ToLocal(&keys)) {
227+
return nullptr;
228+
}
223229
uint32_t keys_length = keys->Length();
224230
for (uint32_t i = 0; i < keys_length; i++) {
225-
Local<Value> key = keys->Get(context, i).ToLocalChecked();
231+
Local<Value> key;
232+
Local<Value> value;
233+
if (!keys->Get(context, i).ToLocal(&key)) {
234+
return nullptr;
235+
}
226236
CHECK(key->IsString());
227-
copy->Set(isolate,
228-
key.As<String>(),
229-
Get(isolate, key.As<String>()).ToLocalChecked());
237+
if (!Get(isolate, key.As<String>()).ToLocal(&value)) {
238+
return nullptr;
239+
}
240+
copy->Set(isolate, key.As<String>(), value.As<String>());
230241
}
231242
return copy;
232243
}
@@ -242,8 +253,12 @@ MaybeLocal<String> MapKVStore::Get(Isolate* isolate, Local<String> key) const {
242253
std::optional<std::string> value = Get(*str);
243254
if (!value.has_value()) return MaybeLocal<String>();
244255
std::string val = value.value();
245-
return String::NewFromUtf8(
246-
isolate, val.data(), NewStringType::kNormal, val.size());
256+
Local<Value> ret;
257+
if (!ToV8Value(isolate->GetCurrentContext(), val).ToLocal(&ret)) {
258+
return {};
259+
}
260+
DCHECK(ret->IsString());
261+
return ret.As<String>();
247262
}
248263

249264
void MapKVStore::Set(Isolate* isolate, Local<String> key, Local<String> value) {
@@ -272,15 +287,16 @@ void MapKVStore::Delete(Isolate* isolate, Local<String> key) {
272287
map_.erase(std::string(*str, str.length()));
273288
}
274289

275-
Local<Array> MapKVStore::Enumerate(Isolate* isolate) const {
290+
MaybeLocal<Array> MapKVStore::Enumerate(Isolate* isolate) const {
276291
Mutex::ScopedLock lock(mutex_);
277292
LocalVector<Value> values(isolate);
278293
values.reserve(map_.size());
279294
for (const auto& pair : map_) {
280-
values.emplace_back(
281-
String::NewFromUtf8(isolate, pair.first.data(),
282-
NewStringType::kNormal, pair.first.size())
283-
.ToLocalChecked());
295+
Local<Value> val;
296+
if (!ToV8Value(isolate->GetCurrentContext(), pair.first).ToLocal(&val)) {
297+
return {};
298+
}
299+
values.emplace_back(val);
284300
}
285301
return Array::New(isolate, values.data(), values.size());
286302
}
@@ -324,7 +340,10 @@ Maybe<void> KVStore::AssignToObject(v8::Isolate* isolate,
324340
v8::Local<v8::Context> context,
325341
v8::Local<v8::Object> object) {
326342
HandleScope scope(isolate);
327-
Local<Array> keys = Enumerate(isolate);
343+
Local<Array> keys;
344+
if (!Enumerate(isolate).ToLocal(&keys)) {
345+
return Nothing<void>();
346+
}
328347
uint32_t keys_length = keys->Length();
329348
for (uint32_t i = 0; i < keys_length; i++) {
330349
Local<Value> key;
@@ -421,6 +440,7 @@ static Intercepted EnvGetter(Local<Name> property,
421440
TraceEnvVar(env, "get", property.As<String>());
422441

423442
if (has_env) {
443+
// ToLocalChecked here is ok since we check IsEmpty above.
424444
info.GetReturnValue().Set(value_string.ToLocalChecked());
425445
return Intercepted::kYes;
426446
}
@@ -502,8 +522,10 @@ static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
502522

503523
TraceEnvVar(env, "enumerate environment variables");
504524

505-
info.GetReturnValue().Set(
506-
env->env_vars()->Enumerate(env->isolate()));
525+
Local<Array> ret;
526+
if (env->env_vars()->Enumerate(env->isolate()).ToLocal(&ret)) {
527+
info.GetReturnValue().Set(ret);
528+
}
507529
}
508530

509531
static Intercepted EnvDefiner(Local<Name> property,

src/node_worker.cc

Lines changed: 4 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ class KVStore {
316316
v8::Local<v8::String> key) const = 0;
317317
virtual int32_t Query(const char* key) const = 0;
318318
virtual void Delete(v8::Isolate* isolate, v8::Local<v8::String> key) = 0;
319-
virtual v8::Local<v8::Array> Enumerate(v8::Isolate* isolate) const = 0;
319+
virtual v8::MaybeLocal<v8::Array> Enumerate(v8::Isolate* isolate) const = 0;
320320

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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy