@@ -36,7 +36,7 @@ using v8::Value;
36
36
37
37
class RealEnvStore final : public KVStore {
38
38
public:
39
- Local <String> Get (Isolate* isolate, Local<String> key) const override ;
39
+ MaybeLocal <String> Get (Isolate* isolate, Local<String> key) const override ;
40
40
void Set (Isolate* isolate, Local<String> key, Local<String> value) override ;
41
41
int32_t Query (Isolate* isolate, Local<String> key) const override ;
42
42
void Delete (Isolate* isolate, Local<String> key) override ;
@@ -45,7 +45,7 @@ class RealEnvStore final : public KVStore {
45
45
46
46
class MapKVStore final : public KVStore {
47
47
public:
48
- Local <String> Get (Isolate* isolate, Local<String> key) const override ;
48
+ MaybeLocal <String> Get (Isolate* isolate, Local<String> key) const override ;
49
49
void Set (Isolate* isolate, Local<String> key, Local<String> value) override ;
50
50
int32_t Query (Isolate* isolate, Local<String> key) const override ;
51
51
void Delete (Isolate* isolate, Local<String> key) override ;
@@ -79,93 +79,73 @@ void DateTimeConfigurationChangeNotification(Isolate* isolate, const T& key) {
79
79
}
80
80
}
81
81
82
- Local <String> RealEnvStore::Get (Isolate* isolate,
83
- Local<String> property) const {
82
+ MaybeLocal <String> RealEnvStore::Get (Isolate* isolate,
83
+ Local<String> property) const {
84
84
Mutex::ScopedLock lock (per_process::env_var_mutex);
85
- # ifdef __POSIX__
85
+
86
86
node::Utf8Value key (isolate, property);
87
- const char * val = getenv (*key);
88
- if (val) {
89
- return String::NewFromUtf8 (isolate, val, NewStringType::kNormal )
90
- .ToLocalChecked ();
87
+ size_t init_sz = 256 ;
88
+ MaybeStackBuffer<char , 256 > val;
89
+ int ret = uv_os_getenv (*key, *val, &init_sz);
90
+
91
+ if (ret == UV_ENOBUFS) {
92
+ // Buffer is not large enough, reallocate to the updated init_sz
93
+ // and fetch env value again.
94
+ val.AllocateSufficientStorage (init_sz);
95
+ ret = uv_os_getenv (*key, *val, &init_sz);
91
96
}
92
- #else // _WIN32
93
- node::TwoByteValue key (isolate, property);
94
- WCHAR buffer[32767 ]; // The maximum size allowed for environment variables.
95
- SetLastError (ERROR_SUCCESS);
96
- DWORD result = GetEnvironmentVariableW (
97
- reinterpret_cast <WCHAR*>(*key), buffer, arraysize (buffer));
98
- // If result >= sizeof buffer the buffer was too small. That should never
99
- // happen. If result == 0 and result != ERROR_SUCCESS the variable was not
100
- // found.
101
- if ((result > 0 || GetLastError () == ERROR_SUCCESS) &&
102
- result < arraysize (buffer)) {
103
- const uint16_t * two_byte_buffer = reinterpret_cast <const uint16_t *>(buffer);
104
- v8::MaybeLocal<String> rc = String::NewFromTwoByte (
105
- isolate, two_byte_buffer, NewStringType::kNormal );
106
- if (rc.IsEmpty ()) {
107
- isolate->ThrowException (ERR_STRING_TOO_LONG (isolate));
108
- return Local<String>();
109
- }
110
- return rc.ToLocalChecked ();
97
+
98
+ if (ret >= 0 ) { // Env key value fetch success.
99
+ MaybeLocal<String> value_string =
100
+ String::NewFromUtf8 (isolate, *val, NewStringType::kNormal , init_sz);
101
+ return value_string;
111
102
}
112
- # endif
113
- return Local <String>();
103
+
104
+ return MaybeLocal <String>();
114
105
}
115
106
116
107
void RealEnvStore::Set (Isolate* isolate,
117
108
Local<String> property,
118
109
Local<String> value) {
119
110
Mutex::ScopedLock lock (per_process::env_var_mutex);
120
- # ifdef __POSIX__
111
+
121
112
node::Utf8Value key (isolate, property);
122
113
node::Utf8Value val (isolate, value);
123
- setenv (*key, *val, 1 );
124
- #else // _WIN32
125
- node::TwoByteValue key (isolate, property);
126
- node::TwoByteValue val (isolate, value);
127
- WCHAR* key_ptr = reinterpret_cast <WCHAR*>(*key);
128
- // Environment variables that start with '=' are read-only.
129
- if (key_ptr[0 ] != L' =' ) {
130
- SetEnvironmentVariableW (key_ptr, reinterpret_cast <WCHAR*>(*val));
131
- }
114
+
115
+ #ifdef _WIN32
116
+ if (key[0 ] == L' =' ) return ;
132
117
#endif
118
+ uv_os_setenv (*key, *val);
133
119
DateTimeConfigurationChangeNotification (isolate, key);
134
120
}
135
121
136
122
int32_t RealEnvStore::Query (Isolate* isolate, Local<String> property) const {
137
123
Mutex::ScopedLock lock (per_process::env_var_mutex);
138
- # ifdef __POSIX__
124
+
139
125
node::Utf8Value key (isolate, property);
140
- if (getenv (*key)) return 0 ;
141
- #else // _WIN32
142
- node::TwoByteValue key (isolate, property);
143
- WCHAR* key_ptr = reinterpret_cast <WCHAR*>(*key);
144
- SetLastError (ERROR_SUCCESS);
145
- if (GetEnvironmentVariableW (key_ptr, nullptr , 0 ) > 0 ||
146
- GetLastError () == ERROR_SUCCESS) {
147
- if (key_ptr[0 ] == L' =' ) {
148
- // Environment variables that start with '=' are hidden and read-only.
149
- return static_cast <int32_t >(v8::ReadOnly) |
150
- static_cast <int32_t >(v8::DontDelete) |
151
- static_cast <int32_t >(v8::DontEnum);
152
- }
153
- return 0 ;
154
- }
126
+ #ifdef _WIN32
127
+ if (key[0 ] == L' =' )
128
+ return static_cast <int32_t >(v8::ReadOnly) |
129
+ static_cast <int32_t >(v8::DontDelete) |
130
+ static_cast <int32_t >(v8::DontEnum);
155
131
#endif
156
- return -1 ;
132
+
133
+ char val[2 ];
134
+ size_t init_sz = sizeof (val);
135
+ int ret = uv_os_getenv (*key, val, &init_sz);
136
+
137
+ if (ret == UV_ENOENT) {
138
+ return -1 ;
139
+ }
140
+
141
+ return 0 ;
157
142
}
158
143
159
144
void RealEnvStore::Delete (Isolate* isolate, Local<String> property) {
160
145
Mutex::ScopedLock lock (per_process::env_var_mutex);
161
- # ifdef __POSIX__
146
+
162
147
node::Utf8Value key (isolate, property);
163
- unsetenv (*key);
164
- #else
165
- node::TwoByteValue key (isolate, property);
166
- WCHAR* key_ptr = reinterpret_cast <WCHAR*>(*key);
167
- SetEnvironmentVariableW (key_ptr, nullptr );
168
- #endif
148
+ uv_os_unsetenv (*key);
169
149
DateTimeConfigurationChangeNotification (isolate, key);
170
150
}
171
151
@@ -231,19 +211,20 @@ std::shared_ptr<KVStore> KVStore::Clone(v8::Isolate* isolate) const {
231
211
for (uint32_t i = 0 ; i < keys_length; i++) {
232
212
Local<Value> key = keys->Get (context, i).ToLocalChecked ();
233
213
CHECK (key->IsString ());
234
- copy->Set (isolate, key.As <String>(), Get (isolate, key.As <String>()));
214
+ copy->Set (isolate,
215
+ key.As <String>(),
216
+ Get (isolate, key.As <String>()).ToLocalChecked ());
235
217
}
236
218
return copy;
237
219
}
238
220
239
- Local <String> MapKVStore::Get (Isolate* isolate, Local<String> key) const {
221
+ MaybeLocal <String> MapKVStore::Get (Isolate* isolate, Local<String> key) const {
240
222
Mutex::ScopedLock lock (mutex_);
241
223
Utf8Value str (isolate, key);
242
224
auto it = map_.find (std::string (*str, str.length ()));
243
225
if (it == map_.end ()) return Local<String>();
244
226
return String::NewFromUtf8 (isolate, it->second .data (),
245
- NewStringType::kNormal , it->second .size ())
246
- .ToLocalChecked ();
227
+ NewStringType::kNormal , it->second .size ());
247
228
}
248
229
249
230
void MapKVStore::Set (Isolate* isolate, Local<String> key, Local<String> value) {
@@ -323,8 +304,11 @@ static void EnvGetter(Local<Name> property,
323
304
return info.GetReturnValue ().SetUndefined ();
324
305
}
325
306
CHECK (property->IsString ());
326
- info.GetReturnValue ().Set (
327
- env->env_vars ()->Get (env->isolate (), property.As <String>()));
307
+ MaybeLocal<String> value_string =
308
+ env->env_vars ()->Get (env->isolate (), property.As <String>());
309
+ if (!value_string.IsEmpty ()) {
310
+ info.GetReturnValue ().Set (value_string.ToLocalChecked ());
311
+ }
328
312
}
329
313
330
314
static void EnvSetter (Local<Name> property,
0 commit comments