Skip to content

Commit 4a5ba60

Browse files
devasciBridgeAR
authored andcommitted
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 c304594 commit 4a5ba60

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
@@ -611,8 +611,8 @@ class KVStore {
611611
KVStore(KVStore&&) = delete;
612612
KVStore& operator=(KVStore&&) = delete;
613613

614-
virtual v8::Local<v8::String> Get(v8::Isolate* isolate,
615-
v8::Local<v8::String> key) const = 0;
614+
virtual v8::MaybeLocal<v8::String> Get(v8::Isolate* isolate,
615+
v8::Local<v8::String> key) const = 0;
616616
virtual void Set(v8::Isolate* isolate,
617617
v8::Local<v8::String> key,
618618
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
@@ -34,7 +34,7 @@ using v8::Value;
3434

3535
class RealEnvStore final : public KVStore {
3636
public:
37-
Local<String> Get(Isolate* isolate, Local<String> key) const override;
37+
MaybeLocal<String> Get(Isolate* isolate, Local<String> key) const override;
3838
void Set(Isolate* isolate, Local<String> key, Local<String> value) override;
3939
int32_t Query(Isolate* isolate, Local<String> key) const override;
4040
void Delete(Isolate* isolate, Local<String> key) override;
@@ -43,7 +43,7 @@ class RealEnvStore final : public KVStore {
4343

4444
class MapKVStore final : public KVStore {
4545
public:
46-
Local<String> Get(Isolate* isolate, Local<String> key) const override;
46+
MaybeLocal<String> Get(Isolate* isolate, Local<String> key) const override;
4747
void Set(Isolate* isolate, Local<String> key, Local<String> value) override;
4848
int32_t Query(Isolate* isolate, Local<String> key) const override;
4949
void Delete(Isolate* isolate, Local<String> key) override;
@@ -64,92 +64,72 @@ Mutex env_var_mutex;
6464
std::shared_ptr<KVStore> system_environment = std::make_shared<RealEnvStore>();
6565
} // namespace per_process
6666

67-
Local<String> RealEnvStore::Get(Isolate* isolate,
68-
Local<String> property) const {
67+
MaybeLocal<String> RealEnvStore::Get(Isolate* isolate,
68+
Local<String> property) const {
6969
Mutex::ScopedLock lock(per_process::env_var_mutex);
70-
#ifdef __POSIX__
70+
7171
node::Utf8Value key(isolate, property);
72-
const char* val = getenv(*key);
73-
if (val) {
74-
return String::NewFromUtf8(isolate, val, NewStringType::kNormal)
75-
.ToLocalChecked();
72+
size_t init_sz = 256;
73+
MaybeStackBuffer<char, 256> val;
74+
int ret = uv_os_getenv(*key, *val, &init_sz);
75+
76+
if (ret == UV_ENOBUFS) {
77+
// Buffer is not large enough, reallocate to the updated init_sz
78+
// and fetch env value again.
79+
val.AllocateSufficientStorage(init_sz);
80+
ret = uv_os_getenv(*key, *val, &init_sz);
7681
}
77-
#else // _WIN32
78-
node::TwoByteValue key(isolate, property);
79-
WCHAR buffer[32767]; // The maximum size allowed for environment variables.
80-
SetLastError(ERROR_SUCCESS);
81-
DWORD result = GetEnvironmentVariableW(
82-
reinterpret_cast<WCHAR*>(*key), buffer, arraysize(buffer));
83-
// If result >= sizeof buffer the buffer was too small. That should never
84-
// happen. If result == 0 and result != ERROR_SUCCESS the variable was not
85-
// found.
86-
if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
87-
result < arraysize(buffer)) {
88-
const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
89-
v8::MaybeLocal<String> rc = String::NewFromTwoByte(
90-
isolate, two_byte_buffer, NewStringType::kNormal);
91-
if (rc.IsEmpty()) {
92-
isolate->ThrowException(ERR_STRING_TOO_LONG(isolate));
93-
return Local<String>();
94-
}
95-
return rc.ToLocalChecked();
82+
83+
if (ret >= 0) { // Env key value fetch success.
84+
MaybeLocal<String> value_string =
85+
String::NewFromUtf8(isolate, *val, NewStringType::kNormal, init_sz);
86+
return value_string;
9687
}
97-
#endif
98-
return Local<String>();
88+
89+
return MaybeLocal<String>();
9990
}
10091

10192
void RealEnvStore::Set(Isolate* isolate,
10293
Local<String> property,
10394
Local<String> value) {
10495
Mutex::ScopedLock lock(per_process::env_var_mutex);
105-
#ifdef __POSIX__
96+
10697
node::Utf8Value key(isolate, property);
10798
node::Utf8Value val(isolate, value);
108-
setenv(*key, *val, 1);
109-
#else // _WIN32
110-
node::TwoByteValue key(isolate, property);
111-
node::TwoByteValue val(isolate, value);
112-
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
113-
// Environment variables that start with '=' are read-only.
114-
if (key_ptr[0] != L'=') {
115-
SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val));
116-
}
99+
100+
#ifdef _WIN32
101+
if (key[0] == L'=') return;
117102
#endif
103+
uv_os_setenv(*key, *val);
118104
}
119105

120106
int32_t RealEnvStore::Query(Isolate* isolate, Local<String> property) const {
121107
Mutex::ScopedLock lock(per_process::env_var_mutex);
122-
#ifdef __POSIX__
108+
123109
node::Utf8Value key(isolate, property);
124-
if (getenv(*key)) return 0;
125-
#else // _WIN32
126-
node::TwoByteValue key(isolate, property);
127-
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
128-
SetLastError(ERROR_SUCCESS);
129-
if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 ||
130-
GetLastError() == ERROR_SUCCESS) {
131-
if (key_ptr[0] == L'=') {
132-
// Environment variables that start with '=' are hidden and read-only.
133-
return static_cast<int32_t>(v8::ReadOnly) |
134-
static_cast<int32_t>(v8::DontDelete) |
135-
static_cast<int32_t>(v8::DontEnum);
136-
}
137-
return 0;
138-
}
110+
#ifdef _WIN32
111+
if (key[0] == L'=')
112+
return static_cast<int32_t>(v8::ReadOnly) |
113+
static_cast<int32_t>(v8::DontDelete) |
114+
static_cast<int32_t>(v8::DontEnum);
139115
#endif
140-
return -1;
116+
117+
char val[2];
118+
size_t init_sz = sizeof(val);
119+
int ret = uv_os_getenv(*key, val, &init_sz);
120+
121+
if (ret == UV_ENOENT) {
122+
return -1;
123+
}
124+
125+
return 0;
141126
}
142127

143128
void RealEnvStore::Delete(Isolate* isolate, Local<String> property) {
144129
Mutex::ScopedLock lock(per_process::env_var_mutex);
145-
#ifdef __POSIX__
130+
146131
node::Utf8Value key(isolate, property);
147-
unsetenv(*key);
148-
#else
149-
node::TwoByteValue key(isolate, property);
150-
WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key);
151-
SetEnvironmentVariableW(key_ptr, nullptr);
152-
#endif
132+
uv_os_unsetenv(*key);
153133
}
154134

155135
Local<Array> RealEnvStore::Enumerate(Isolate* isolate) const {
@@ -214,19 +194,20 @@ std::shared_ptr<KVStore> KVStore::Clone(v8::Isolate* isolate) const {
214194
for (uint32_t i = 0; i < keys_length; i++) {
215195
Local<Value> key = keys->Get(context, i).ToLocalChecked();
216196
CHECK(key->IsString());
217-
copy->Set(isolate, key.As<String>(), Get(isolate, key.As<String>()));
197+
copy->Set(isolate,
198+
key.As<String>(),
199+
Get(isolate, key.As<String>()).ToLocalChecked());
218200
}
219201
return copy;
220202
}
221203

222-
Local<String> MapKVStore::Get(Isolate* isolate, Local<String> key) const {
204+
MaybeLocal<String> MapKVStore::Get(Isolate* isolate, Local<String> key) const {
223205
Mutex::ScopedLock lock(mutex_);
224206
Utf8Value str(isolate, key);
225207
auto it = map_.find(std::string(*str, str.length()));
226208
if (it == map_.end()) return Local<String>();
227209
return String::NewFromUtf8(isolate, it->second.data(),
228-
NewStringType::kNormal, it->second.size())
229-
.ToLocalChecked();
210+
NewStringType::kNormal, it->second.size());
230211
}
231212

232213
void MapKVStore::Set(Isolate* isolate, Local<String> key, Local<String> value) {
@@ -306,8 +287,11 @@ static void EnvGetter(Local<Name> property,
306287
return info.GetReturnValue().SetUndefined();
307288
}
308289
CHECK(property->IsString());
309-
info.GetReturnValue().Set(
310-
env->env_vars()->Get(env->isolate(), property.As<String>()));
290+
MaybeLocal<String> value_string =
291+
env->env_vars()->Get(env->isolate(), property.As<String>());
292+
if (!value_string.IsEmpty()) {
293+
info.GetReturnValue().Set(value_string.ToLocalChecked());
294+
}
311295
}
312296

313297
static void EnvSetter(Local<Name> property,

0 commit comments

Comments
 (0)