GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_process_object.cc Lines: 81 83 97.6 %
Date: 2022-12-07 04:23:16 Branches: 41 66 62.1 %

Line Branch Exec Source
1
#include "env-inl.h"
2
#include "node_errors.h"
3
#include "node_external_reference.h"
4
#include "node_internals.h"
5
#include "node_metadata.h"
6
#include "node_options-inl.h"
7
#include "node_process-inl.h"
8
#include "node_realm-inl.h"
9
#include "node_revert.h"
10
#include "util-inl.h"
11
12
#include <climits>  // PATH_MAX
13
14
namespace node {
15
using v8::Context;
16
using v8::DEFAULT;
17
using v8::EscapableHandleScope;
18
using v8::Function;
19
using v8::FunctionCallbackInfo;
20
using v8::FunctionTemplate;
21
using v8::Integer;
22
using v8::Isolate;
23
using v8::Local;
24
using v8::MaybeLocal;
25
using v8::Name;
26
using v8::NewStringType;
27
using v8::None;
28
using v8::Object;
29
using v8::PropertyCallbackInfo;
30
using v8::SideEffectType;
31
using v8::String;
32
using v8::Value;
33
34
122
static void ProcessTitleGetter(Local<Name> property,
35
                               const PropertyCallbackInfo<Value>& info) {
36
122
  std::string title = GetProcessTitle("node");
37
366
  info.GetReturnValue().Set(
38
122
      String::NewFromUtf8(info.GetIsolate(), title.data(),
39
244
                          NewStringType::kNormal, title.size())
40
      .ToLocalChecked());
41
122
}
42
43
105
static void ProcessTitleSetter(Local<Name> property,
44
                               Local<Value> value,
45
                               const PropertyCallbackInfo<void>& info) {
46
210
  node::Utf8Value title(info.GetIsolate(), value);
47

209
  TRACE_EVENT_METADATA1(
48
      "__metadata", "process_name", "name", TRACE_STR_COPY(*title));
49
105
  uv_set_process_title(*title);
50
105
}
51
52
241
static void DebugPortGetter(Local<Name> property,
53
                            const PropertyCallbackInfo<Value>& info) {
54
241
  Environment* env = Environment::GetCurrent(info);
55
241
  ExclusiveAccess<HostPort>::Scoped host_port(env->inspector_host_port());
56
241
  int port = host_port->port();
57
482
  info.GetReturnValue().Set(port);
58
241
}
59
60
29
static void DebugPortSetter(Local<Name> property,
61
                            Local<Value> value,
62
                            const PropertyCallbackInfo<void>& info) {
63
29
  Environment* env = Environment::GetCurrent(info);
64
29
  int32_t port = value->Int32Value(env->context()).FromMaybe(0);
65
66

29
  if ((port != 0 && port < 1024) || port > 65535) {
67
9
    return THROW_ERR_OUT_OF_RANGE(
68
      env,
69
9
      "process.debugPort must be 0 or in range 1024 to 65535");
70
  }
71
72
40
  ExclusiveAccess<HostPort>::Scoped host_port(env->inspector_host_port());
73
20
  host_port->set_port(static_cast<int>(port));
74
}
75
76
116
static void GetParentProcessId(Local<Name> property,
77
                               const PropertyCallbackInfo<Value>& info) {
78
116
  info.GetReturnValue().Set(uv_os_getppid());
79
116
}
80
81
800
MaybeLocal<Object> CreateProcessObject(Realm* realm) {
82
800
  Isolate* isolate = realm->isolate();
83
800
  EscapableHandleScope scope(isolate);
84
800
  Local<Context> context = realm->context();
85
86
800
  Local<FunctionTemplate> process_template = FunctionTemplate::New(isolate);
87
800
  process_template->SetClassName(realm->env()->process_string());
88
  Local<Function> process_ctor;
89
  Local<Object> process;
90
2400
  if (!process_template->GetFunction(context).ToLocal(&process_ctor) ||
91

2400
      !process_ctor->NewInstance(context).ToLocal(&process)) {
92
    return MaybeLocal<Object>();
93
  }
94
95
  // process[exit_info_private_symbol]
96
800
  if (process
97
800
          ->SetPrivate(context,
98
                       realm->env()->exit_info_private_symbol(),
99
1600
                       realm->env()->exit_info().GetJSArray())
100
800
          .IsNothing()) {
101
    return {};
102
  }
103
104
  // process.version
105
2400
  READONLY_PROPERTY(
106
      process, "version", FIXED_ONE_BYTE_STRING(isolate, NODE_VERSION));
107
108
  // process.versions
109
800
  Local<Object> versions = Object::New(isolate);
110
1600
  READONLY_PROPERTY(process, "versions", versions);
111
112
#define V(key)                                                                 \
113
  if (!per_process::metadata.versions.key.empty()) {                           \
114
    READONLY_STRING_PROPERTY(                                                  \
115
        versions, #key, per_process::metadata.versions.key);                   \
116
  }
117








55200
  NODE_VERSIONS_KEYS(V)
118
#undef V
119
120
  // process.arch
121
3200
  READONLY_STRING_PROPERTY(process, "arch", per_process::metadata.arch);
122
123
  // process.platform
124
2400
  READONLY_STRING_PROPERTY(process, "platform", per_process::metadata.platform);
125
126
  // process.release
127
800
  Local<Object> release = Object::New(isolate);
128
2400
  READONLY_PROPERTY(process, "release", release);
129
2400
  READONLY_STRING_PROPERTY(release, "name", per_process::metadata.release.name);
130
#if NODE_VERSION_IS_LTS
131
  READONLY_STRING_PROPERTY(release, "lts", per_process::metadata.release.lts);
132
#endif  // NODE_VERSION_IS_LTS
133
134
#ifdef NODE_HAS_RELEASE_URLS
135
  READONLY_STRING_PROPERTY(
136
      release, "sourceUrl", per_process::metadata.release.source_url);
137
  READONLY_STRING_PROPERTY(
138
      release, "headersUrl", per_process::metadata.release.headers_url);
139
#ifdef _WIN32
140
  READONLY_STRING_PROPERTY(
141
      release, "libUrl", per_process::metadata.release.lib_url);
142
#endif  // _WIN32
143
#endif  // NODE_HAS_RELEASE_URLS
144
145
  // process._rawDebug: may be overwritten later in JS land, but should be
146
  // available from the beginning for debugging purposes
147
800
  SetMethod(context, process, "_rawDebug", RawDebug);
148
149
800
  return scope.Escape(process);
150
}
151
152
6395
void PatchProcessObject(const FunctionCallbackInfo<Value>& args) {
153
6395
  Isolate* isolate = args.GetIsolate();
154
6395
  Local<Context> context = isolate->GetCurrentContext();
155
6395
  Environment* env = Environment::GetCurrent(context);
156
6395
  CHECK(args[0]->IsObject());
157
12790
  Local<Object> process = args[0].As<Object>();
158
159
  // process.title
160

19185
  CHECK(process
161
            ->SetAccessor(
162
                context,
163
                FIXED_ONE_BYTE_STRING(isolate, "title"),
164
                ProcessTitleGetter,
165
                env->owns_process_state() ? ProcessTitleSetter : nullptr,
166
                Local<Value>(),
167
                DEFAULT,
168
                None,
169
                SideEffectType::kHasNoSideEffect)
170
            .FromJust());
171
172
  // process.argv
173
6395
  process->Set(context,
174
               FIXED_ONE_BYTE_STRING(isolate, "argv"),
175
25580
               ToV8Value(context, env->argv()).ToLocalChecked()).Check();
176
177
  // process.execArgv
178
6395
  process->Set(context,
179
               FIXED_ONE_BYTE_STRING(isolate, "execArgv"),
180
6395
               ToV8Value(context, env->exec_argv())
181
25580
                   .ToLocalChecked()).Check();
182
183
25580
  READONLY_PROPERTY(process, "pid",
184
                    Integer::New(isolate, uv_os_getpid()));
185
186
25580
  CHECK(process->SetAccessor(context,
187
                             FIXED_ONE_BYTE_STRING(isolate, "ppid"),
188
                             GetParentProcessId).FromJust());
189
190
  // --security-revert flags
191
#define V(code, _, __)                                                        \
192
  do {                                                                        \
193
    if (IsReverted(SECURITY_REVERT_ ## code)) {                               \
194
      READONLY_PROPERTY(process, "REVERT_" #code, True(isolate));             \
195
    }                                                                         \
196
  } while (0);
197
  SECURITY_REVERSIONS(V)
198
#undef V
199
200
  // process.execPath
201
  process
202
6395
      ->Set(context,
203
            FIXED_ONE_BYTE_STRING(isolate, "execPath"),
204
6395
            String::NewFromUtf8(isolate,
205
6395
                                env->exec_path().c_str(),
206
                                NewStringType::kInternalized,
207
6395
                                env->exec_path().size())
208
25580
                .ToLocalChecked())
209
      .Check();
210
211
  // process.debugPort
212

19185
  CHECK(process
213
            ->SetAccessor(context,
214
                          FIXED_ONE_BYTE_STRING(isolate, "debugPort"),
215
                          DebugPortGetter,
216
                          env->owns_process_state() ? DebugPortSetter : nullptr,
217
                          Local<Value>())
218
            .FromJust());
219
6395
}
220
221
5639
void RegisterProcessExternalReferences(ExternalReferenceRegistry* registry) {
222
5639
  registry->Register(RawDebug);
223
5639
  registry->Register(GetParentProcessId);
224
5639
  registry->Register(DebugPortSetter);
225
5639
  registry->Register(DebugPortGetter);
226
5639
  registry->Register(ProcessTitleSetter);
227
5639
  registry->Register(ProcessTitleGetter);
228
5639
}
229
230
}  // namespace node
231
232
5639
NODE_BINDING_EXTERNAL_REFERENCE(process_object,
233
                                node::RegisterProcessExternalReferences)