From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sattard@slack-corp.com>
Date: Wed, 22 May 2019 13:34:18 -0700
Subject: chore: prevent / warn non context-aware native modules being loaded

This should be updated to take advantage of https://github.com/nodejs/node/pull/29631
once we stop warning and begin to unilaterally prevent non-context aware modules
from being loaded.

diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js
index af69dfc9e71b54a9d7eda0daa498396008aba610..f52e8a09f689bafcfdca39e71822ff3cbf898349 100644
--- a/lib/internal/bootstrap/pre_execution.js
+++ b/lib/internal/bootstrap/pre_execution.js
@@ -95,10 +95,12 @@ function patchProcessObject(expandArgv1) {
   if (expandArgv1 && process.argv[1] &&
       !StringPrototypeStartsWith(process.argv[1], '-')) {
     // Expand process.argv[1] into a full path.
-    const path = require('path');
-    try {
-      process.argv[1] = path.resolve(process.argv[1]);
-    } catch {}
+    if (!process.argv[1] || !process.argv[1].startsWith('electron/js2c')) {
+      const path = require('path');
+      try {
+        process.argv[1] = path.resolve(process.argv[1]);
+      } catch {}
+    }
   }
 
   // TODO(joyeecheung): most of these should be deprecated and removed,
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
index 541c18d8032c5247433367f9e04c946cf203d475..b04e3f1fc56a86abe18f924e4d9b7fb517aea74d 100644
--- a/lib/internal/modules/cjs/loader.js
+++ b/lib/internal/modules/cjs/loader.js
@@ -1037,6 +1037,13 @@ Module.prototype._compile = function(content, filename) {
   if (getOptionValue('--inspect-brk') && process._eval == null) {
     if (!resolvedArgv) {
       // We enter the repl if we're not given a filename argument.
+      // process._firstFileName is used by Embedders to tell node what
+      // the first "real" file is when they use themselves as the entry
+      // point
+      if (process._firstFileName) {
+        resolvedArgv = process._firstFileName
+        delete process._firstFileName
+      } else
       if (process.argv[1]) {
         try {
           resolvedArgv = Module._resolveFilename(process.argv[1], null, false);
diff --git a/src/env-inl.h b/src/env-inl.h
index c1853f81b68bd22d20fb99877f4c500a384e9545..623e9d4e429c03bb267539a318166f3ef3b9c501 100644
--- a/src/env-inl.h
+++ b/src/env-inl.h
@@ -550,6 +550,14 @@ inline bool Environment::force_context_aware() const {
   return options_->force_context_aware;
 }
 
+inline void Environment::set_warn_context_aware(bool value) {
+  options_->warn_context_aware = value;
+}
+
+inline bool Environment::warn_context_aware() const {
+  return options_->warn_context_aware;
+}
+
 inline void Environment::set_abort_on_uncaught_exception(bool value) {
   options_->abort_on_uncaught_exception = value;
 }
diff --git a/src/env.h b/src/env.h
index f89365a1aa7ffacbb423e01a68f484992751f76f..38d17f4e18aa38fde2c2f59a9816c8fb0f65fd51 100644
--- a/src/env.h
+++ b/src/env.h
@@ -949,6 +949,8 @@ class Environment : public MemoryRetainer {
 
   inline void set_force_context_aware(bool value);
   inline bool force_context_aware() const;
+  inline void set_warn_context_aware(bool value);
+  inline bool warn_context_aware() const;
 
   // This stores whether the --abort-on-uncaught-exception flag was passed
   // to Node.
diff --git a/src/node_binding.cc b/src/node_binding.cc
index ca5a01f925a2ae69ba4295d82316e546f45c60cd..f85ab2332a1c0267bd50d5f979d90e55c84a2990 100644
--- a/src/node_binding.cc
+++ b/src/node_binding.cc
@@ -3,6 +3,7 @@
 #include <atomic>
 #include "env-inl.h"
 #include "node_native_module_env.h"
+#include "node_process.h"
 #include "util.h"
 
 #if HAVE_OPENSSL
@@ -463,8 +464,20 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
       if (mp->nm_context_register_func == nullptr) {
         if (env->force_context_aware()) {
           dlib->Close();
-          THROW_ERR_NON_CONTEXT_AWARE_DISABLED(env);
+          char errmsg[1024];
+          snprintf(errmsg,
+                   sizeof(errmsg),
+                   "Loading non-context-aware native module in renderer: '%s', but app.allowRendererProcessReuse is true. See https://github.com/electron/electron/issues/18397.",
+                   *filename);
+          env->ThrowError(errmsg);
           return false;
+        } else if (env->warn_context_aware()) {
+          char errmsg[1024];
+          snprintf(errmsg,
+                   sizeof(errmsg),
+                   "Loading non-context-aware native module in renderer: '%s'. This is deprecated, see https://github.com/electron/electron/issues/18397.",
+                   *filename);
+          ProcessEmitWarningGeneric(env, errmsg, "Electron");
         }
       }
       mp->nm_dso_handle = dlib->handle_;
diff --git a/src/node_options.cc b/src/node_options.cc
index e7dc220f5c3fcab40c9a669a79b3a41b7e9f8cbf..01143e122387db8220d6e0cd0124ae08e082d0c8 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -371,6 +371,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
             "disable loading non-context-aware addons",
             &EnvironmentOptions::force_context_aware,
             kAllowedInEnvironment);
+  AddOption("--warn-context-aware",
+          "warn when loading non-context-aware addons",
+          &EnvironmentOptions::warn_context_aware,
+          kAllowedInEnvironment);
   AddOption("--pending-deprecation",
             "emit pending deprecation warnings",
             &EnvironmentOptions::pending_deprecation,
diff --git a/src/node_options.h b/src/node_options.h
index bd63fcb0485c77e24becdf2392c453f3b2c4cdba..2af8f82ec5e6995b9ba340fddbc4943f0374198f 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -121,6 +121,7 @@ class EnvironmentOptions : public Options {
   bool no_force_async_hooks_checks = false;
   bool no_warnings = false;
   bool force_context_aware = false;
+  bool warn_context_aware = false;
   bool pending_deprecation = false;
   bool preserve_symlinks = false;
   bool preserve_symlinks_main = false;
