Skip to content

Commit d3840bc

Browse files
addaleaxBethGriggs
authored andcommitted
src: allow per-Environment set of env vars
Abstract the `process.env` backing mechanism in C++ to allow different kinds of backing stores for `process.env` for different Environments. PR-URL: #26544 Fixes: #24947 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Signed-off-by: Beth Griggs <Bethany.Griggs@uk.ibm.com>
1 parent 78fad32 commit d3840bc

File tree

6 files changed

+176
-84
lines changed

6 files changed

+176
-84
lines changed

src/env-inl.h

+8
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,14 @@ inline uint64_t Environment::timer_base() const {
447447
return timer_base_;
448448
}
449449

450+
inline std::shared_ptr<KVStore> Environment::envvars() {
451+
return envvars_;
452+
}
453+
454+
inline void Environment::set_envvars(std::shared_ptr<KVStore> envvars) {
455+
envvars_ = envvars;
456+
}
457+
450458
inline bool Environment::printed_error() const {
451459
return printed_error_;
452460
}

src/env.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ Environment::Environment(IsolateData* isolate_data,
207207
set_as_callback_data_template(templ);
208208
}
209209

210+
set_envvars(per_process::real_environment);
211+
210212
// We create new copies of the per-Environment option sets, so that it is
211213
// easier to modify them after Environment creation. The defaults are
212214
// part of the per-Isolate option set, for which in turn the defaults are
@@ -250,7 +252,7 @@ Environment::Environment(IsolateData* isolate_data,
250252
should_abort_on_uncaught_toggle_[0] = 1;
251253

252254
std::string debug_cats;
253-
credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats);
255+
credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats, this);
254256
set_debug_categories(debug_cats, true);
255257

256258
isolate()->GetHeapProfiler()->AddBuildEmbedderGraphCallback(

src/env.h

+20
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,23 @@ class AsyncRequest : public MemoryRetainer {
532532
std::atomic_bool stopped_ {true};
533533
};
534534

535+
class KVStore {
536+
public:
537+
virtual v8::Local<v8::String> Get(v8::Isolate* isolate,
538+
v8::Local<v8::String> key) const = 0;
539+
virtual void Set(v8::Isolate* isolate,
540+
v8::Local<v8::String> key,
541+
v8::Local<v8::String> value) = 0;
542+
virtual int32_t Query(v8::Isolate* isolate,
543+
v8::Local<v8::String> key) const = 0;
544+
virtual void Delete(v8::Isolate* isolate, v8::Local<v8::String> key) = 0;
545+
virtual v8::Local<v8::Array> Enumerate(v8::Isolate* isolate) const = 0;
546+
};
547+
548+
namespace per_process {
549+
extern std::shared_ptr<KVStore> real_environment;
550+
}
551+
535552
class AsyncHooks {
536553
public:
537554
// Reason for both UidFields and Fields are that one is stored as a double*
@@ -781,6 +798,8 @@ class Environment {
781798
inline ImmediateInfo* immediate_info();
782799
inline TickInfo* tick_info();
783800
inline uint64_t timer_base() const;
801+
inline std::shared_ptr<KVStore> envvars();
802+
inline void set_envvars(std::shared_ptr<KVStore> envvars);
784803

785804
inline IsolateData* isolate_data() const;
786805

@@ -1075,6 +1094,7 @@ class Environment {
10751094
ImmediateInfo immediate_info_;
10761095
TickInfo tick_info_;
10771096
const uint64_t timer_base_;
1097+
std::shared_ptr<KVStore> envvars_;
10781098
bool printed_error_ = false;
10791099
bool emit_env_nonstring_warning_ = true;
10801100
bool emit_err_name_warning_ = true;

src/node_credentials.cc

+21-3
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@ using v8::Array;
1515
using v8::Context;
1616
using v8::Function;
1717
using v8::FunctionCallbackInfo;
18+
using v8::HandleScope;
1819
using v8::Isolate;
1920
using v8::Local;
2021
using v8::MaybeLocal;
22+
using v8::NewStringType;
2123
using v8::Object;
2224
using v8::String;
25+
using v8::TryCatch;
2326
using v8::Uint32;
2427
using v8::Value;
2528

@@ -30,13 +33,27 @@ bool linux_at_secure = false;
3033
namespace credentials {
3134

3235
// Look up environment variable unless running as setuid root.
33-
bool SafeGetenv(const char* key, std::string* text) {
36+
bool SafeGetenv(const char* key, std::string* text, Environment* env) {
3437
#if !defined(__CloudABI__) && !defined(_WIN32)
3538
if (per_process::linux_at_secure || getuid() != geteuid() ||
3639
getgid() != getegid())
3740
goto fail;
3841
#endif
3942

43+
if (env != nullptr) {
44+
HandleScope handle_scope(env->isolate());
45+
TryCatch ignore_errors(env->isolate());
46+
MaybeLocal<String> value = env->envvars()->Get(
47+
env->isolate(),
48+
String::NewFromUtf8(env->isolate(), key, NewStringType::kNormal)
49+
.ToLocalChecked());
50+
if (value.IsEmpty()) goto fail;
51+
String::Utf8Value utf8_value(env->isolate(), value.ToLocalChecked());
52+
if (*utf8_value == nullptr) goto fail;
53+
*text = std::string(*utf8_value, utf8_value.length());
54+
return true;
55+
}
56+
4057
{
4158
Mutex::ScopedLock lock(per_process::env_var_mutex);
4259
if (const char* value = getenv(key)) {
@@ -52,10 +69,11 @@ bool SafeGetenv(const char* key, std::string* text) {
5269

5370
static void SafeGetenv(const FunctionCallbackInfo<Value>& args) {
5471
CHECK(args[0]->IsString());
55-
Isolate* isolate = args.GetIsolate();
72+
Environment* env = Environment::GetCurrent(args);
73+
Isolate* isolate = env->isolate();
5674
Utf8Value strenvtag(isolate, args[0]);
5775
std::string text;
58-
if (!SafeGetenv(*strenvtag, &text)) return;
76+
if (!SafeGetenv(*strenvtag, &text, env)) return;
5977
Local<Value> result =
6078
ToV8Value(isolate->GetCurrentContext(), text).ToLocalChecked();
6179
args.GetReturnValue().Set(result);

0 commit comments

Comments
 (0)