@@ -26,7 +26,6 @@ using v8::Maybe;
2626using v8::MaybeLocal;
2727using v8::Name;
2828using v8::NamedPropertyHandlerConfiguration;
29- using v8::NewStringType;
3029using v8::Nothing;
3130using v8::Object;
3231using 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
5150class 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
249264void 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
509531static Intercepted EnvDefiner (Local<Name> property,
0 commit comments