Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: nodejs/node
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1824222ee4cd9059032a7dc2ba99ea198c3eb3c4
Choose a base ref
..
head repository: nodejs/node
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4c3db74a3994079f9b7b79032a3da96a98b217a0
Choose a head ref
36 changes: 36 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
@@ -984,6 +984,41 @@ surface on other platforms, but the performance impact may be severe.
This flag is inherited from V8 and is subject to change upstream. It may
disappear in a non-semver-major release.

### `--env-file=config`

> Stability: 1.1 - Active development
<!-- YAML
added: REPLACEME
-->

Loads environment variables from a file relative to the current directory,
making them available to applications on `process.env`. The [environment
variables which configure Node.js][environment_variables], such as `NODE_OPTIONS`,
are parsed and applied. If the same variable is defined in the environment and
in the file, the value from the environment takes precedence.

The format of the file should be one line per key-value pair of environment
variable name and value separated by `=`:

```text
PORT=3000
```

Any text after a `#` is treated as a comment:

```text
# This is a comment
PORT=3000 # This is also a comment
```

Values can start and end with the following quotes: `\`, `"` or `'`.
They are omitted from the values.

```text
USERNAME="nodejs" # will result in `nodejs` as the value.
```

### `--max-http-header-size=size`

<!-- YAML
@@ -2647,6 +2682,7 @@ done
[debugger]: debugger.md
[debugging security implications]: https://nodejs.org/en/docs/guides/debugging-getting-started/#security-implications
[emit_warning]: process.md#processemitwarningwarning-options
[environment_variables]: #environment-variables
[filtering tests by name]: test.md#filtering-tests-by-name
[jitless]: https://v8.dev/blog/jitless
[libuv threadpool documentation]: https://docs.libuv.org/en/latest/threadpool.html
13 changes: 13 additions & 0 deletions doc/api/process.md
Original file line number Diff line number Diff line change
@@ -3517,6 +3517,19 @@ throw an error.
Using this function is mutually exclusive with using the deprecated
[`domain`][] built-in module.
## `process.sourceMapsEnabled`
<!-- YAML
added: REPLACEME
-->
> Stability: 1 - Experimental
* {boolean}
The `process.sourceMapsEnabled` property returns whether the
[Source Map v3][Source Map] support for stack traces is enabled.
## `process.stderr`
* {Stream}
9 changes: 9 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
@@ -326,13 +326,22 @@ process.emitWarning = emitWarning;

{
const {
getSourceMapsEnabled,
setSourceMapsEnabled,
maybeCacheGeneratedSourceMap,
} = require('internal/source_map/source_map_cache');
const {
setMaybeCacheGeneratedSourceMap,
} = internalBinding('errors');

ObjectDefineProperty(process, 'sourceMapsEnabled', {
__proto__: null,
enumerable: true,
configurable: true,
get() {
return getSourceMapsEnabled();
},
});
process.setSourceMapsEnabled = setSourceMapsEnabled;
// The C++ land calls back to maybeCacheGeneratedSourceMap()
// when code is generated by user with eval() or new Function()
2 changes: 2 additions & 0 deletions node.gyp
Original file line number Diff line number Diff line change
@@ -100,6 +100,7 @@
'src/node_contextify.cc',
'src/node_credentials.cc',
'src/node_dir.cc',
'src/node_dotenv.cc',
'src/node_env_var.cc',
'src/node_errors.cc',
'src/node_external_reference.cc',
@@ -214,6 +215,7 @@
'src/node_context_data.h',
'src/node_contextify.h',
'src/node_dir.h',
'src/node_dotenv.h',
'src/node_errors.h',
'src/node_exit_code.h',
'src/node_external_reference.h',
9 changes: 4 additions & 5 deletions src/env.cc
Original file line number Diff line number Diff line change
@@ -684,7 +684,7 @@ void Environment::TryLoadAddon(
}
}

std::string Environment::GetCwd() {
std::string Environment::GetCwd(const std::string& exec_path) {
char cwd[PATH_MAX_BYTES];
size_t size = PATH_MAX_BYTES;
const int err = uv_cwd(cwd, &size);
@@ -696,7 +696,6 @@ std::string Environment::GetCwd() {

// This can fail if the cwd is deleted. In that case, fall back to
// exec_path.
const std::string& exec_path = exec_path_;
return exec_path.substr(0, exec_path.find_last_of(kPathSeparator));
}

@@ -730,7 +729,7 @@ std::unique_ptr<v8::BackingStore> Environment::release_managed_buffer(
return bs;
}

std::string GetExecPath(const std::vector<std::string>& argv) {
std::string Environment::GetExecPath(const std::vector<std::string>& argv) {
char exec_path_buf[2 * PATH_MAX];
size_t exec_path_len = sizeof(exec_path_buf);
std::string exec_path;
@@ -772,7 +771,7 @@ Environment::Environment(IsolateData* isolate_data,
timer_base_(uv_now(isolate_data->event_loop())),
exec_argv_(exec_args),
argv_(args),
exec_path_(GetExecPath(args)),
exec_path_(Environment::GetExecPath(args)),
exit_info_(
isolate_, kExitInfoFieldCount, MAYBE_FIELD_PTR(env_info, exit_info)),
should_abort_on_uncaught_toggle_(
@@ -1922,7 +1921,7 @@ size_t Environment::NearHeapLimitCallback(void* data,

std::string dir = env->options()->diagnostic_dir;
if (dir.empty()) {
dir = env->GetCwd();
dir = Environment::GetCwd(env->exec_path_);
}
DiagnosticFilename name(env, "Heap", "heapsnapshot");
std::string filename = dir + kPathSeparator + (*name);
5 changes: 3 additions & 2 deletions src/env.h
Original file line number Diff line number Diff line change
@@ -588,6 +588,9 @@ class Environment : public MemoryRetainer {

SET_MEMORY_INFO_NAME(Environment)

static std::string GetExecPath(const std::vector<std::string>& argv);
static std::string GetCwd(const std::string& exec_path);

inline size_t SelfSize() const override;
bool IsRootNode() const override { return true; }
void MemoryInfo(MemoryTracker* tracker) const override;
@@ -604,8 +607,6 @@ class Environment : public MemoryRetainer {
// Should be called before InitializeInspector()
void InitializeDiagnostics();

std::string GetCwd();

#if HAVE_INSPECTOR
// If the environment is created for a worker, pass parent_handle and
// the ownership if transferred into the Environment.
4 changes: 3 additions & 1 deletion src/heap_utils.cc
Original file line number Diff line number Diff line change
@@ -456,7 +456,9 @@ void TriggerHeapSnapshot(const FunctionCallbackInfo<Value>& args) {
if (filename_v->IsUndefined()) {
DiagnosticFilename name(env, "Heap", "heapsnapshot");
THROW_IF_INSUFFICIENT_PERMISSIONS(
env, permission::PermissionScope::kFileSystemWrite, env->GetCwd());
env,
permission::PermissionScope::kFileSystemWrite,
Environment::GetCwd(env->exec_path()));
if (WriteSnapshot(env, *name, options).IsNothing()) return;
if (String::NewFromUtf8(isolate, *name).ToLocal(&filename_v)) {
args.GetReturnValue().Set(filename_v);
6 changes: 4 additions & 2 deletions src/inspector_profiler.cc
Original file line number Diff line number Diff line change
@@ -431,7 +431,8 @@ void StartProfilers(Environment* env) {
if (env->options()->cpu_prof) {
const std::string& dir = env->options()->cpu_prof_dir;
env->set_cpu_prof_interval(env->options()->cpu_prof_interval);
env->set_cpu_prof_dir(dir.empty() ? env->GetCwd() : dir);
env->set_cpu_prof_dir(dir.empty() ? Environment::GetCwd(env->exec_path())
: dir);
if (env->options()->cpu_prof_name.empty()) {
DiagnosticFilename filename(env, "CPU", "cpuprofile");
env->set_cpu_prof_name(*filename);
@@ -446,7 +447,8 @@ void StartProfilers(Environment* env) {
if (env->options()->heap_prof) {
const std::string& dir = env->options()->heap_prof_dir;
env->set_heap_prof_interval(env->options()->heap_prof_interval);
env->set_heap_prof_dir(dir.empty() ? env->GetCwd() : dir);
env->set_heap_prof_dir(dir.empty() ? Environment::GetCwd(env->exec_path())
: dir);
if (env->options()->heap_prof_name.empty()) {
DiagnosticFilename filename(env, "Heap", "heapprofile");
env->set_heap_prof_name(*filename);
26 changes: 23 additions & 3 deletions src/node.cc
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "node.h"
#include "node_dotenv.h"

// ========== local headers ==========

@@ -140,6 +141,10 @@ using v8::Value;

namespace per_process {

// node_dotenv.h
// Instance is used to store environment variables including NODE_OPTIONS.
node::Dotenv dotenv_file = Dotenv();

// node_revert.h
// Bit flag used to track security reverts.
unsigned int reverted_cve = 0;
@@ -305,6 +310,10 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
}
#endif

if (env->options()->has_env_file_string) {
per_process::dotenv_file.SetEnvironment(env);
}

// TODO(joyeecheung): move these conditions into JS land and let the
// deserialize main function take precedence. For workers, we need to
// move the pre-execution part into a different file that can be
@@ -831,11 +840,22 @@ static ExitCode InitializeNodeWithArgsInternal(

HandleEnvOptions(per_process::cli_options->per_isolate->per_env);

std::string node_options;
auto file_path = node::Dotenv::GetPathFromArgs(*argv);

if (file_path.has_value()) {
auto cwd = Environment::GetCwd(Environment::GetExecPath(*argv));
std::string path = cwd + kPathSeparator + file_path.value();
CHECK(!per_process::v8_initialized);
per_process::dotenv_file.ParsePath(path);
per_process::dotenv_file.AssignNodeOptionsIfAvailable(&node_options);
}

#if !defined(NODE_WITHOUT_NODE_OPTIONS)
if (!(flags & ProcessInitializationFlags::kDisableNodeOptionsEnv)) {
std::string node_options;

if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) {
// NODE_OPTIONS environment variable is preferred over the file one.
if (credentials::SafeGetenv("NODE_OPTIONS", &node_options) ||
!node_options.empty()) {
std::vector<std::string> env_argv =
ParseNodeOptionsEnvVar(node_options, errors);

1 change: 0 additions & 1 deletion src/node_credentials.cc
Original file line number Diff line number Diff line change
@@ -123,7 +123,6 @@ bool SafeGetenv(const char* key,
}

fail:
text->clear();
return false;
}

Loading