diff options
author | Devendra Satram <devendra4sci@gmail.com> | 2019-04-19 18:03:18 +0530 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-09-12 19:11:33 +0200 |
commit | b354d12599ea9e2b29e6b26dedae82b9b474d424 (patch) | |
tree | 468fe9b063c8801f9904211a2218af0698df4b97 /src | |
parent | 03eec137a2114092503de04c2c3291af00a50a4e (diff) | |
download | android-node-v8-b354d12599ea9e2b29e6b26dedae82b9b474d424.tar.gz android-node-v8-b354d12599ea9e2b29e6b26dedae82b9b474d424.tar.bz2 android-node-v8-b354d12599ea9e2b29e6b26dedae82b9b474d424.zip |
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: https://github.com/nodejs/node/issues/27211
Refs: http://docs.libuv.org/en/v1.x/misc.html
PR-URL: https://github.com/nodejs/node/pull/27310
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/env.h | 4 | ||||
-rw-r--r-- | src/inspector_profiler.cc | 3 | ||||
-rw-r--r-- | src/node_env_var.cc | 124 |
3 files changed, 58 insertions, 73 deletions
@@ -610,8 +610,8 @@ class KVStore { KVStore(KVStore&&) = delete; KVStore& operator=(KVStore&&) = delete; - virtual v8::Local<v8::String> Get(v8::Isolate* isolate, - v8::Local<v8::String> key) const = 0; + virtual v8::MaybeLocal<v8::String> Get(v8::Isolate* isolate, + v8::Local<v8::String> key) const = 0; virtual void Set(v8::Isolate* isolate, v8::Local<v8::String> key, v8::Local<v8::String> value) = 0; diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index e5e01dc3c9..867f145ff5 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -340,7 +340,8 @@ std::string GetCwd(Environment* env) { void StartProfilers(Environment* env) { Isolate* isolate = env->isolate(); Local<String> coverage_str = env->env_vars()->Get( - isolate, FIXED_ONE_BYTE_STRING(isolate, "NODE_V8_COVERAGE")); + isolate, FIXED_ONE_BYTE_STRING(isolate, "NODE_V8_COVERAGE")) + .FromMaybe(Local<String>()); if (!coverage_str.IsEmpty() && coverage_str->Length() > 0) { CHECK_NULL(env->coverage_connection()); env->set_coverage_connection(std::make_unique<V8CoverageConnection>(env)); diff --git a/src/node_env_var.cc b/src/node_env_var.cc index ef2b78d664..2c1af65b86 100644 --- a/src/node_env_var.cc +++ b/src/node_env_var.cc @@ -36,7 +36,7 @@ using v8::Value; class RealEnvStore final : public KVStore { public: - Local<String> Get(Isolate* isolate, Local<String> key) const override; + MaybeLocal<String> Get(Isolate* isolate, Local<String> key) const override; void Set(Isolate* isolate, Local<String> key, Local<String> value) override; int32_t Query(Isolate* isolate, Local<String> key) const override; void Delete(Isolate* isolate, Local<String> key) override; @@ -45,7 +45,7 @@ class RealEnvStore final : public KVStore { class MapKVStore final : public KVStore { public: - Local<String> Get(Isolate* isolate, Local<String> key) const override; + MaybeLocal<String> Get(Isolate* isolate, Local<String> key) const override; void Set(Isolate* isolate, Local<String> key, Local<String> value) override; int32_t Query(Isolate* isolate, Local<String> key) const override; void Delete(Isolate* isolate, Local<String> key) override; @@ -79,93 +79,73 @@ void DateTimeConfigurationChangeNotification(Isolate* isolate, const T& key) { } } -Local<String> RealEnvStore::Get(Isolate* isolate, - Local<String> property) const { +MaybeLocal<String> RealEnvStore::Get(Isolate* isolate, + Local<String> property) const { Mutex::ScopedLock lock(per_process::env_var_mutex); -#ifdef __POSIX__ + node::Utf8Value key(isolate, property); - const char* val = getenv(*key); - if (val) { - return String::NewFromUtf8(isolate, val, NewStringType::kNormal) - .ToLocalChecked(); + size_t init_sz = 256; + MaybeStackBuffer<char, 256> val; + int ret = uv_os_getenv(*key, *val, &init_sz); + + if (ret == UV_ENOBUFS) { + // Buffer is not large enough, reallocate to the updated init_sz + // and fetch env value again. + val.AllocateSufficientStorage(init_sz); + ret = uv_os_getenv(*key, *val, &init_sz); } -#else // _WIN32 - node::TwoByteValue key(isolate, property); - WCHAR buffer[32767]; // The maximum size allowed for environment variables. - SetLastError(ERROR_SUCCESS); - DWORD result = GetEnvironmentVariableW( - reinterpret_cast<WCHAR*>(*key), buffer, arraysize(buffer)); - // If result >= sizeof buffer the buffer was too small. That should never - // happen. If result == 0 and result != ERROR_SUCCESS the variable was not - // found. - if ((result > 0 || GetLastError() == ERROR_SUCCESS) && - result < arraysize(buffer)) { - const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer); - v8::MaybeLocal<String> rc = String::NewFromTwoByte( - isolate, two_byte_buffer, NewStringType::kNormal); - if (rc.IsEmpty()) { - isolate->ThrowException(ERR_STRING_TOO_LONG(isolate)); - return Local<String>(); - } - return rc.ToLocalChecked(); + + if (ret >= 0) { // Env key value fetch success. + MaybeLocal<String> value_string = + String::NewFromUtf8(isolate, *val, NewStringType::kNormal, init_sz); + return value_string; } -#endif - return Local<String>(); + + return MaybeLocal<String>(); } void RealEnvStore::Set(Isolate* isolate, Local<String> property, Local<String> value) { Mutex::ScopedLock lock(per_process::env_var_mutex); -#ifdef __POSIX__ + node::Utf8Value key(isolate, property); node::Utf8Value val(isolate, value); - setenv(*key, *val, 1); -#else // _WIN32 - node::TwoByteValue key(isolate, property); - node::TwoByteValue val(isolate, value); - WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key); - // Environment variables that start with '=' are read-only. - if (key_ptr[0] != L'=') { - SetEnvironmentVariableW(key_ptr, reinterpret_cast<WCHAR*>(*val)); - } + +#ifdef _WIN32 + if (key[0] == L'=') return; #endif + uv_os_setenv(*key, *val); DateTimeConfigurationChangeNotification(isolate, key); } int32_t RealEnvStore::Query(Isolate* isolate, Local<String> property) const { Mutex::ScopedLock lock(per_process::env_var_mutex); -#ifdef __POSIX__ + node::Utf8Value key(isolate, property); - if (getenv(*key)) return 0; -#else // _WIN32 - node::TwoByteValue key(isolate, property); - WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key); - SetLastError(ERROR_SUCCESS); - if (GetEnvironmentVariableW(key_ptr, nullptr, 0) > 0 || - GetLastError() == ERROR_SUCCESS) { - if (key_ptr[0] == L'=') { - // Environment variables that start with '=' are hidden and read-only. - return static_cast<int32_t>(v8::ReadOnly) | - static_cast<int32_t>(v8::DontDelete) | - static_cast<int32_t>(v8::DontEnum); - } - return 0; - } +#ifdef _WIN32 + if (key[0] == L'=') + return static_cast<int32_t>(v8::ReadOnly) | + static_cast<int32_t>(v8::DontDelete) | + static_cast<int32_t>(v8::DontEnum); #endif - return -1; + + char val[2]; + size_t init_sz = sizeof(val); + int ret = uv_os_getenv(*key, val, &init_sz); + + if (ret == UV_ENOENT) { + return -1; + } + + return 0; } void RealEnvStore::Delete(Isolate* isolate, Local<String> property) { Mutex::ScopedLock lock(per_process::env_var_mutex); -#ifdef __POSIX__ + node::Utf8Value key(isolate, property); - unsetenv(*key); -#else - node::TwoByteValue key(isolate, property); - WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key); - SetEnvironmentVariableW(key_ptr, nullptr); -#endif + uv_os_unsetenv(*key); DateTimeConfigurationChangeNotification(isolate, key); } @@ -231,19 +211,20 @@ std::shared_ptr<KVStore> KVStore::Clone(v8::Isolate* isolate) const { for (uint32_t i = 0; i < keys_length; i++) { Local<Value> key = keys->Get(context, i).ToLocalChecked(); CHECK(key->IsString()); - copy->Set(isolate, key.As<String>(), Get(isolate, key.As<String>())); + copy->Set(isolate, + key.As<String>(), + Get(isolate, key.As<String>()).ToLocalChecked()); } return copy; } -Local<String> MapKVStore::Get(Isolate* isolate, Local<String> key) const { +MaybeLocal<String> MapKVStore::Get(Isolate* isolate, Local<String> key) const { Mutex::ScopedLock lock(mutex_); Utf8Value str(isolate, key); auto it = map_.find(std::string(*str, str.length())); if (it == map_.end()) return Local<String>(); return String::NewFromUtf8(isolate, it->second.data(), - NewStringType::kNormal, it->second.size()) - .ToLocalChecked(); + NewStringType::kNormal, it->second.size()); } void MapKVStore::Set(Isolate* isolate, Local<String> key, Local<String> value) { @@ -323,8 +304,11 @@ static void EnvGetter(Local<Name> property, return info.GetReturnValue().SetUndefined(); } CHECK(property->IsString()); - info.GetReturnValue().Set( - env->env_vars()->Get(env->isolate(), property.As<String>())); + MaybeLocal<String> value_string = + env->env_vars()->Get(env->isolate(), property.As<String>()); + if (!value_string.IsEmpty()) { + info.GetReturnValue().Set(value_string.ToLocalChecked()); + } } static void EnvSetter(Local<Name> property, |