• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "env-inl.h"
2 #include "node_internals.h"
3 #include "node_options-inl.h"
4 #include "node_metadata.h"
5 #include "node_process-inl.h"
6 #include "node_revert.h"
7 #include "util-inl.h"
8 
9 #include <climits>  // PATH_MAX
10 
11 namespace node {
12 using v8::Context;
13 using v8::DEFAULT;
14 using v8::EscapableHandleScope;
15 using v8::Function;
16 using v8::FunctionCallbackInfo;
17 using v8::FunctionTemplate;
18 using v8::Integer;
19 using v8::Isolate;
20 using v8::Local;
21 using v8::MaybeLocal;
22 using v8::Name;
23 using v8::NewStringType;
24 using v8::None;
25 using v8::Object;
26 using v8::PropertyCallbackInfo;
27 using v8::SideEffectType;
28 using v8::String;
29 using v8::Value;
30 
ProcessTitleGetter(Local<Name> property,const PropertyCallbackInfo<Value> & info)31 static void ProcessTitleGetter(Local<Name> property,
32                                const PropertyCallbackInfo<Value>& info) {
33   std::string title = GetProcessTitle("node");
34   info.GetReturnValue().Set(
35       String::NewFromUtf8(info.GetIsolate(), title.data(),
36                           NewStringType::kNormal, title.size())
37       .ToLocalChecked());
38 }
39 
ProcessTitleSetter(Local<Name> property,Local<Value> value,const PropertyCallbackInfo<void> & info)40 static void ProcessTitleSetter(Local<Name> property,
41                                Local<Value> value,
42                                const PropertyCallbackInfo<void>& info) {
43   node::Utf8Value title(info.GetIsolate(), value);
44   TRACE_EVENT_METADATA1(
45       "__metadata", "process_name", "name", TRACE_STR_COPY(*title));
46   uv_set_process_title(*title);
47 }
48 
DebugPortGetter(Local<Name> property,const PropertyCallbackInfo<Value> & info)49 static void DebugPortGetter(Local<Name> property,
50                             const PropertyCallbackInfo<Value>& info) {
51   Environment* env = Environment::GetCurrent(info);
52   ExclusiveAccess<HostPort>::Scoped host_port(env->inspector_host_port());
53   int port = host_port->port();
54   info.GetReturnValue().Set(port);
55 }
56 
DebugPortSetter(Local<Name> property,Local<Value> value,const PropertyCallbackInfo<void> & info)57 static void DebugPortSetter(Local<Name> property,
58                             Local<Value> value,
59                             const PropertyCallbackInfo<void>& info) {
60   Environment* env = Environment::GetCurrent(info);
61   int32_t port = value->Int32Value(env->context()).FromMaybe(0);
62   ExclusiveAccess<HostPort>::Scoped host_port(env->inspector_host_port());
63   host_port->set_port(static_cast<int>(port));
64 }
65 
GetParentProcessId(Local<Name> property,const PropertyCallbackInfo<Value> & info)66 static void GetParentProcessId(Local<Name> property,
67                                const PropertyCallbackInfo<Value>& info) {
68   info.GetReturnValue().Set(uv_os_getppid());
69 }
70 
CreateProcessObject(Environment * env)71 MaybeLocal<Object> CreateProcessObject(Environment* env) {
72   Isolate* isolate = env->isolate();
73   EscapableHandleScope scope(isolate);
74   Local<Context> context = env->context();
75 
76   Local<FunctionTemplate> process_template = FunctionTemplate::New(isolate);
77   process_template->SetClassName(env->process_string());
78   Local<Function> process_ctor;
79   Local<Object> process;
80   if (!process_template->GetFunction(context).ToLocal(&process_ctor) ||
81       !process_ctor->NewInstance(context).ToLocal(&process)) {
82     return MaybeLocal<Object>();
83   }
84 
85   // process.version
86   READONLY_PROPERTY(process,
87                     "version",
88                     FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
89 
90   // process.versions
91   Local<Object> versions = Object::New(env->isolate());
92   READONLY_PROPERTY(process, "versions", versions);
93 
94 #define V(key)                                                                 \
95   if (!per_process::metadata.versions.key.empty()) {                           \
96     READONLY_STRING_PROPERTY(                                                  \
97         versions, #key, per_process::metadata.versions.key);                   \
98   }
99   NODE_VERSIONS_KEYS(V)
100 #undef V
101 
102   // process.arch
103   READONLY_STRING_PROPERTY(process, "arch", per_process::metadata.arch);
104 
105   // process.platform
106   READONLY_STRING_PROPERTY(process, "platform", per_process::metadata.platform);
107 
108   // process.release
109   Local<Object> release = Object::New(env->isolate());
110   READONLY_PROPERTY(process, "release", release);
111   READONLY_STRING_PROPERTY(release, "name", per_process::metadata.release.name);
112 #if NODE_VERSION_IS_LTS
113   READONLY_STRING_PROPERTY(release, "lts", per_process::metadata.release.lts);
114 #endif  // NODE_VERSION_IS_LTS
115 
116 #ifdef NODE_HAS_RELEASE_URLS
117   READONLY_STRING_PROPERTY(
118       release, "sourceUrl", per_process::metadata.release.source_url);
119   READONLY_STRING_PROPERTY(
120       release, "headersUrl", per_process::metadata.release.headers_url);
121 #ifdef _WIN32
122   READONLY_STRING_PROPERTY(
123       release, "libUrl", per_process::metadata.release.lib_url);
124 #endif  // _WIN32
125 #endif  // NODE_HAS_RELEASE_URLS
126 
127   // process._rawDebug: may be overwritten later in JS land, but should be
128   // available from the beginning for debugging purposes
129   env->SetMethod(process, "_rawDebug", RawDebug);
130 
131   return scope.Escape(process);
132 }
133 
PatchProcessObject(const FunctionCallbackInfo<Value> & args)134 void PatchProcessObject(const FunctionCallbackInfo<Value>& args) {
135   Isolate* isolate = args.GetIsolate();
136   Local<Context> context = isolate->GetCurrentContext();
137   Environment* env = Environment::GetCurrent(context);
138   CHECK(args[0]->IsObject());
139   Local<Object> process = args[0].As<Object>();
140 
141   // process.title
142   CHECK(process
143             ->SetAccessor(
144                 context,
145                 FIXED_ONE_BYTE_STRING(isolate, "title"),
146                 ProcessTitleGetter,
147                 env->owns_process_state() ? ProcessTitleSetter : nullptr,
148                 Local<Value>(),
149                 DEFAULT,
150                 None,
151                 SideEffectType::kHasNoSideEffect)
152             .FromJust());
153 
154   // process.argv
155   process->Set(context,
156                FIXED_ONE_BYTE_STRING(isolate, "argv"),
157                ToV8Value(context, env->argv()).ToLocalChecked()).Check();
158 
159   // process.execArgv
160   process->Set(context,
161                FIXED_ONE_BYTE_STRING(isolate, "execArgv"),
162                ToV8Value(context, env->exec_argv())
163                    .ToLocalChecked()).Check();
164 
165   READONLY_PROPERTY(process, "pid",
166                     Integer::New(isolate, uv_os_getpid()));
167 
168   CHECK(process->SetAccessor(context,
169                              FIXED_ONE_BYTE_STRING(isolate, "ppid"),
170                              GetParentProcessId).FromJust());
171 
172   // --security-revert flags
173 #define V(code, _, __)                                                        \
174   do {                                                                        \
175     if (IsReverted(SECURITY_REVERT_ ## code)) {                               \
176       READONLY_PROPERTY(process, "REVERT_" #code, True(isolate));             \
177     }                                                                         \
178   } while (0);
179   SECURITY_REVERSIONS(V)
180 #undef V
181 
182   // process.execPath
183   process
184       ->Set(context,
185             FIXED_ONE_BYTE_STRING(isolate, "execPath"),
186             String::NewFromUtf8(isolate,
187                                 env->exec_path().c_str(),
188                                 NewStringType::kInternalized,
189                                 env->exec_path().size())
190                 .ToLocalChecked())
191       .Check();
192 
193   // process.debugPort
194   CHECK(process
195             ->SetAccessor(context,
196                           FIXED_ONE_BYTE_STRING(isolate, "debugPort"),
197                           DebugPortGetter,
198                           env->owns_process_state() ? DebugPortSetter : nullptr,
199                           Local<Value>())
200             .FromJust());
201 }
202 
203 }  // namespace node
204