@@ -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
5151class 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
509528static Intercepted EnvDefiner (Local<Name> property,
0 commit comments