Skip to content

Commit b354d12

Browse files
devasciaddaleax
authored andcommittedSep 12, 2019
src: modified RealEnvStore methods to use libuv functions
Modified RealEnvStore::Get, Set, Query and Delete methods to use libuv methods environment variables operations instead of using os specific logic and switches. Fixes: #27211 Refs: http://docs.libuv.org/en/v1.x/misc.html PR-URL: #27310 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 03eec13 commit b354d12

File tree

3 files changed

+58
-73
lines changed

3 files changed

+58
-73
lines changed
 

‎src/env.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,8 @@ class KVStore {
610610
KVStore(KVStore&&) = delete;
611611
KVStore& operator=(KVStore&&) = delete;
612612

613-
virtual v8::Local<v8::String> Get(v8::Isolate* isolate,
614-
v8::Local<v8::String> key) const = 0;
613+
virtual v8::MaybeLocal<v8::String> Get(v8::Isolate* isolate,
614+
v8::Local<v8::String> key) const = 0;
615615
virtual void Set(v8::Isolate* isolate,
616616
v8::Local<v8::String> key,
617617
v8::Local<v8::String> value) = 0;

‎src/inspector_profiler.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ std::string GetCwd(Environment* env) {
340340
void StartProfilers(Environment* env) {
341341
Isolate* isolate = env->isolate();
342342
Local<String> coverage_str = env->env_vars()->Get(
343-
isolate, FIXED_ONE_BYTE_STRING(isolate, "NODE_V8_COVERAGE"));
343+
isolate, FIXED_ONE_BYTE_STRING(isolate, "NODE_V8_COVERAGE"))
344+
.FromMaybe(Local<String>());
344345
if (!coverage_str.IsEmpty() && coverage_str->Length() > 0) {
345346
CHECK_NULL(env->coverage_connection());
346347
env->set_coverage_connection(std::make_unique<V8CoverageConnection>(env));

‎src/node_env_var.cc

+54-70
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ using v8::Value;
3636

3737
class RealEnvStore final : public KVStore {
3838
public:
39-
Local<String> Get(Isolate* isolate, Local<String> key) const override;
39+
MaybeLocal<String> Get(Isolate* isolate, Local<String> key) const override;
4040
void Set(Isolate* isolate, Local<String> key, Local<String> value) override;
4141
int32_t Query(Isolate* isolate, Local<String> key) const override;
4242
void Delete(Isolate* isolate, Local<String> key) override;
@@ -45,7 +45,7 @@ class RealEnvStore final : public KVStore {
4545

4646
class MapKVStore final : public KVStore {
4747
public:
48-
Local<String> Get(Isolate* isolate, Local<String> key) const override;
48+
MaybeLocal<String> Get(Isolate* isolate, Local<String> key) const override;
4949
void Set(Isolate* isolate, Local<String> key, Local<String> value) override;
5050
int32_t Query(Isolate* isolate, Local<String> key) const override;
5151
void Delete(Isolate* isolate, Local<String> key) override;
@@ -79,93 +79,73 @@ void DateTimeConfigurationChangeNotification(Isolate* isolate, const T& key) {
7979
}
8080
}
8181

82-
Local<String> RealEnvStore::Get(Isolate* isolate,
83-
Local<String> property) const {
82+
MaybeLocal<String> RealEnvStore::Get(Isolate* isolate,
83+
Local<String> property) const {
8484
Mutex::ScopedLock lock(per_process::env_var_mutex);
85-
#ifdef __POSIX__
85+
8686
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);
9196
}
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;
111102
}
112-
#endif
113-
return Local<String>();
103+
104+
return MaybeLocal<String>();
114105
}
115106

116107
void RealEnvStore::Set(Isolate* isolate,
117108
Local<String> property,
118109
Local<String> value) {
119110
Mutex::ScopedLock lock(per_process::env_var_mutex);
120-
#ifdef __POSIX__
111+
121112
node::Utf8Value key(isolate, property);
122113
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;
132117
#endif
118+
uv_os_setenv(*key, *val);
133119
DateTimeConfigurationChangeNotification(isolate, key);
134120
}
135121

136122
int32_t RealEnvStore::Query(Isolate* isolate, Local<String> property) const {
137123
Mutex::ScopedLock lock(per_process::env_var_mutex);
138-
#ifdef __POSIX__
124+
139125
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);
155131
#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;
157142
}
158143

159144
void RealEnvStore::Delete(Isolate* isolate, Local<String> property) {
160145
Mutex::ScopedLock lock(per_process::env_var_mutex);
161-
#ifdef __POSIX__
146+
162147
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);
169149
DateTimeConfigurationChangeNotification(isolate, key);
170150
}
171151

@@ -231,19 +211,20 @@ std::shared_ptr<KVStore> KVStore::Clone(v8::Isolate* isolate) const {
231211
for (uint32_t i = 0; i < keys_length; i++) {
232212
Local<Value> key = keys->Get(context, i).ToLocalChecked();
233213
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());
235217
}
236218
return copy;
237219
}
238220

239-
Local<String> MapKVStore::Get(Isolate* isolate, Local<String> key) const {
221+
MaybeLocal<String> MapKVStore::Get(Isolate* isolate, Local<String> key) const {
240222
Mutex::ScopedLock lock(mutex_);
241223
Utf8Value str(isolate, key);
242224
auto it = map_.find(std::string(*str, str.length()));
243225
if (it == map_.end()) return Local<String>();
244226
return String::NewFromUtf8(isolate, it->second.data(),
245-
NewStringType::kNormal, it->second.size())
246-
.ToLocalChecked();
227+
NewStringType::kNormal, it->second.size());
247228
}
248229

249230
void MapKVStore::Set(Isolate* isolate, Local<String> key, Local<String> value) {
@@ -323,8 +304,11 @@ static void EnvGetter(Local<Name> property,
323304
return info.GetReturnValue().SetUndefined();
324305
}
325306
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+
}
328312
}
329313

330314
static void EnvSetter(Local<Name> property,

0 commit comments

Comments
 (0)
Please sign in to comment.