11cb0ef41Sopenharmony_ci#include "env-inl.h"
21cb0ef41Sopenharmony_ci#include "node_errors.h"
31cb0ef41Sopenharmony_ci#include "node_external_reference.h"
41cb0ef41Sopenharmony_ci#include "node_internals.h"
51cb0ef41Sopenharmony_ci#include "node_metadata.h"
61cb0ef41Sopenharmony_ci#include "node_options-inl.h"
71cb0ef41Sopenharmony_ci#include "node_process-inl.h"
81cb0ef41Sopenharmony_ci#include "node_realm-inl.h"
91cb0ef41Sopenharmony_ci#include "node_revert.h"
101cb0ef41Sopenharmony_ci#include "util-inl.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include <climits>  // PATH_MAX
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace node {
151cb0ef41Sopenharmony_ciusing v8::Context;
161cb0ef41Sopenharmony_ciusing v8::DEFAULT;
171cb0ef41Sopenharmony_ciusing v8::EscapableHandleScope;
181cb0ef41Sopenharmony_ciusing v8::Function;
191cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo;
201cb0ef41Sopenharmony_ciusing v8::FunctionTemplate;
211cb0ef41Sopenharmony_ciusing v8::Integer;
221cb0ef41Sopenharmony_ciusing v8::Isolate;
231cb0ef41Sopenharmony_ciusing v8::Local;
241cb0ef41Sopenharmony_ciusing v8::MaybeLocal;
251cb0ef41Sopenharmony_ciusing v8::Name;
261cb0ef41Sopenharmony_ciusing v8::NewStringType;
271cb0ef41Sopenharmony_ciusing v8::None;
281cb0ef41Sopenharmony_ciusing v8::Object;
291cb0ef41Sopenharmony_ciusing v8::PropertyCallbackInfo;
301cb0ef41Sopenharmony_ciusing v8::SideEffectType;
311cb0ef41Sopenharmony_ciusing v8::String;
321cb0ef41Sopenharmony_ciusing v8::Value;
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_cistatic void ProcessTitleGetter(Local<Name> property,
351cb0ef41Sopenharmony_ci                               const PropertyCallbackInfo<Value>& info) {
361cb0ef41Sopenharmony_ci  std::string title = GetProcessTitle("node");
371cb0ef41Sopenharmony_ci  info.GetReturnValue().Set(
381cb0ef41Sopenharmony_ci      String::NewFromUtf8(info.GetIsolate(), title.data(),
391cb0ef41Sopenharmony_ci                          NewStringType::kNormal, title.size())
401cb0ef41Sopenharmony_ci      .ToLocalChecked());
411cb0ef41Sopenharmony_ci}
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_cistatic void ProcessTitleSetter(Local<Name> property,
441cb0ef41Sopenharmony_ci                               Local<Value> value,
451cb0ef41Sopenharmony_ci                               const PropertyCallbackInfo<void>& info) {
461cb0ef41Sopenharmony_ci  node::Utf8Value title(info.GetIsolate(), value);
471cb0ef41Sopenharmony_ci  TRACE_EVENT_METADATA1(
481cb0ef41Sopenharmony_ci      "__metadata", "process_name", "name", TRACE_STR_COPY(*title));
491cb0ef41Sopenharmony_ci  uv_set_process_title(*title);
501cb0ef41Sopenharmony_ci}
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_cistatic void DebugPortGetter(Local<Name> property,
531cb0ef41Sopenharmony_ci                            const PropertyCallbackInfo<Value>& info) {
541cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(info);
551cb0ef41Sopenharmony_ci  ExclusiveAccess<HostPort>::Scoped host_port(env->inspector_host_port());
561cb0ef41Sopenharmony_ci  int port = host_port->port();
571cb0ef41Sopenharmony_ci  info.GetReturnValue().Set(port);
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_cistatic void DebugPortSetter(Local<Name> property,
611cb0ef41Sopenharmony_ci                            Local<Value> value,
621cb0ef41Sopenharmony_ci                            const PropertyCallbackInfo<void>& info) {
631cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(info);
641cb0ef41Sopenharmony_ci  int32_t port = value->Int32Value(env->context()).FromMaybe(0);
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  if ((port != 0 && port < 1024) || port > 65535) {
671cb0ef41Sopenharmony_ci    return THROW_ERR_OUT_OF_RANGE(
681cb0ef41Sopenharmony_ci      env,
691cb0ef41Sopenharmony_ci      "process.debugPort must be 0 or in range 1024 to 65535");
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci  ExclusiveAccess<HostPort>::Scoped host_port(env->inspector_host_port());
731cb0ef41Sopenharmony_ci  host_port->set_port(static_cast<int>(port));
741cb0ef41Sopenharmony_ci}
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_cistatic void GetParentProcessId(Local<Name> property,
771cb0ef41Sopenharmony_ci                               const PropertyCallbackInfo<Value>& info) {
781cb0ef41Sopenharmony_ci  info.GetReturnValue().Set(uv_os_getppid());
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ciMaybeLocal<Object> CreateProcessObject(Realm* realm) {
821cb0ef41Sopenharmony_ci  Isolate* isolate = realm->isolate();
831cb0ef41Sopenharmony_ci  EscapableHandleScope scope(isolate);
841cb0ef41Sopenharmony_ci  Local<Context> context = realm->context();
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  Local<FunctionTemplate> process_template = FunctionTemplate::New(isolate);
871cb0ef41Sopenharmony_ci  process_template->SetClassName(realm->env()->process_string());
881cb0ef41Sopenharmony_ci  Local<Function> process_ctor;
891cb0ef41Sopenharmony_ci  Local<Object> process;
901cb0ef41Sopenharmony_ci  if (!process_template->GetFunction(context).ToLocal(&process_ctor) ||
911cb0ef41Sopenharmony_ci      !process_ctor->NewInstance(context).ToLocal(&process)) {
921cb0ef41Sopenharmony_ci    return MaybeLocal<Object>();
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  // process[exiting_aliased_Uint32Array]
961cb0ef41Sopenharmony_ci  if (process
971cb0ef41Sopenharmony_ci          ->SetPrivate(context,
981cb0ef41Sopenharmony_ci                       realm->env()->exiting_aliased_Uint32Array(),
991cb0ef41Sopenharmony_ci                       realm->env()->exiting().GetJSArray())
1001cb0ef41Sopenharmony_ci          .IsNothing()) {
1011cb0ef41Sopenharmony_ci    return {};
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  // process.version
1051cb0ef41Sopenharmony_ci  READONLY_PROPERTY(
1061cb0ef41Sopenharmony_ci      process, "version", FIXED_ONE_BYTE_STRING(isolate, NODE_VERSION));
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  Local<Object> versions = Object::New(isolate);
1091cb0ef41Sopenharmony_ci  // Node.js version is always on the top
1101cb0ef41Sopenharmony_ci  READONLY_STRING_PROPERTY(
1111cb0ef41Sopenharmony_ci      versions, "node", per_process::metadata.versions.node);
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci#define V(key) +1
1141cb0ef41Sopenharmony_ci  std::pair<std::string_view, std::string_view>
1151cb0ef41Sopenharmony_ci      versions_array[NODE_VERSIONS_KEYS(V)];
1161cb0ef41Sopenharmony_ci#undef V
1171cb0ef41Sopenharmony_ci  auto* slot = &versions_array[0];
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci#define V(key)                                                                 \
1201cb0ef41Sopenharmony_ci  do {                                                                         \
1211cb0ef41Sopenharmony_ci    *slot++ = std::pair<std::string_view, std::string_view>(                   \
1221cb0ef41Sopenharmony_ci        #key, per_process::metadata.versions.key);                             \
1231cb0ef41Sopenharmony_ci  } while (0);
1241cb0ef41Sopenharmony_ci  NODE_VERSIONS_KEYS(V)
1251cb0ef41Sopenharmony_ci#undef V
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  std::sort(&versions_array[0],
1281cb0ef41Sopenharmony_ci            &versions_array[arraysize(versions_array)],
1291cb0ef41Sopenharmony_ci            [](auto& a, auto& b) { return a.first < b.first; });
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ci  for (const auto& version : versions_array) {
1321cb0ef41Sopenharmony_ci    versions
1331cb0ef41Sopenharmony_ci        ->DefineOwnProperty(
1341cb0ef41Sopenharmony_ci            context,
1351cb0ef41Sopenharmony_ci            OneByteString(isolate, version.first.data(), version.first.size()),
1361cb0ef41Sopenharmony_ci            OneByteString(
1371cb0ef41Sopenharmony_ci                isolate, version.second.data(), version.second.size()),
1381cb0ef41Sopenharmony_ci            v8::ReadOnly)
1391cb0ef41Sopenharmony_ci        .Check();
1401cb0ef41Sopenharmony_ci  }
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  // process.versions
1431cb0ef41Sopenharmony_ci  READONLY_PROPERTY(process, "versions", versions);
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  // process.arch
1461cb0ef41Sopenharmony_ci  READONLY_STRING_PROPERTY(process, "arch", per_process::metadata.arch);
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  // process.platform
1491cb0ef41Sopenharmony_ci  READONLY_STRING_PROPERTY(process, "platform", per_process::metadata.platform);
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  // process.release
1521cb0ef41Sopenharmony_ci  Local<Object> release = Object::New(isolate);
1531cb0ef41Sopenharmony_ci  READONLY_PROPERTY(process, "release", release);
1541cb0ef41Sopenharmony_ci  READONLY_STRING_PROPERTY(release, "name", per_process::metadata.release.name);
1551cb0ef41Sopenharmony_ci#if NODE_VERSION_IS_LTS
1561cb0ef41Sopenharmony_ci  READONLY_STRING_PROPERTY(release, "lts", per_process::metadata.release.lts);
1571cb0ef41Sopenharmony_ci#endif  // NODE_VERSION_IS_LTS
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci#ifdef NODE_HAS_RELEASE_URLS
1601cb0ef41Sopenharmony_ci  READONLY_STRING_PROPERTY(
1611cb0ef41Sopenharmony_ci      release, "sourceUrl", per_process::metadata.release.source_url);
1621cb0ef41Sopenharmony_ci  READONLY_STRING_PROPERTY(
1631cb0ef41Sopenharmony_ci      release, "headersUrl", per_process::metadata.release.headers_url);
1641cb0ef41Sopenharmony_ci#ifdef _WIN32
1651cb0ef41Sopenharmony_ci  READONLY_STRING_PROPERTY(
1661cb0ef41Sopenharmony_ci      release, "libUrl", per_process::metadata.release.lib_url);
1671cb0ef41Sopenharmony_ci#endif  // _WIN32
1681cb0ef41Sopenharmony_ci#endif  // NODE_HAS_RELEASE_URLS
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  // process._rawDebug: may be overwritten later in JS land, but should be
1711cb0ef41Sopenharmony_ci  // available from the beginning for debugging purposes
1721cb0ef41Sopenharmony_ci  SetMethod(context, process, "_rawDebug", RawDebug);
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  return scope.Escape(process);
1751cb0ef41Sopenharmony_ci}
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_civoid PatchProcessObject(const FunctionCallbackInfo<Value>& args) {
1781cb0ef41Sopenharmony_ci  Isolate* isolate = args.GetIsolate();
1791cb0ef41Sopenharmony_ci  Local<Context> context = isolate->GetCurrentContext();
1801cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(context);
1811cb0ef41Sopenharmony_ci  CHECK(args[0]->IsObject());
1821cb0ef41Sopenharmony_ci  Local<Object> process = args[0].As<Object>();
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci  // process.title
1851cb0ef41Sopenharmony_ci  CHECK(process
1861cb0ef41Sopenharmony_ci            ->SetAccessor(
1871cb0ef41Sopenharmony_ci                context,
1881cb0ef41Sopenharmony_ci                FIXED_ONE_BYTE_STRING(isolate, "title"),
1891cb0ef41Sopenharmony_ci                ProcessTitleGetter,
1901cb0ef41Sopenharmony_ci                env->owns_process_state() ? ProcessTitleSetter : nullptr,
1911cb0ef41Sopenharmony_ci                Local<Value>(),
1921cb0ef41Sopenharmony_ci                DEFAULT,
1931cb0ef41Sopenharmony_ci                None,
1941cb0ef41Sopenharmony_ci                SideEffectType::kHasNoSideEffect)
1951cb0ef41Sopenharmony_ci            .FromJust());
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci  // process.argv
1981cb0ef41Sopenharmony_ci  process->Set(context,
1991cb0ef41Sopenharmony_ci               FIXED_ONE_BYTE_STRING(isolate, "argv"),
2001cb0ef41Sopenharmony_ci               ToV8Value(context, env->argv()).ToLocalChecked()).Check();
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci  // process.execArgv
2031cb0ef41Sopenharmony_ci  process->Set(context,
2041cb0ef41Sopenharmony_ci               FIXED_ONE_BYTE_STRING(isolate, "execArgv"),
2051cb0ef41Sopenharmony_ci               ToV8Value(context, env->exec_argv())
2061cb0ef41Sopenharmony_ci                   .ToLocalChecked()).Check();
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  READONLY_PROPERTY(process, "pid",
2091cb0ef41Sopenharmony_ci                    Integer::New(isolate, uv_os_getpid()));
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci  CHECK(process->SetAccessor(context,
2121cb0ef41Sopenharmony_ci                             FIXED_ONE_BYTE_STRING(isolate, "ppid"),
2131cb0ef41Sopenharmony_ci                             GetParentProcessId).FromJust());
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci  // --security-revert flags
2161cb0ef41Sopenharmony_ci#define V(code, _, __)                                                        \
2171cb0ef41Sopenharmony_ci  do {                                                                        \
2181cb0ef41Sopenharmony_ci    if (IsReverted(SECURITY_REVERT_ ## code)) {                               \
2191cb0ef41Sopenharmony_ci      READONLY_PROPERTY(process, "REVERT_" #code, True(isolate));             \
2201cb0ef41Sopenharmony_ci    }                                                                         \
2211cb0ef41Sopenharmony_ci  } while (0);
2221cb0ef41Sopenharmony_ci  SECURITY_REVERSIONS(V)
2231cb0ef41Sopenharmony_ci#undef V
2241cb0ef41Sopenharmony_ci
2251cb0ef41Sopenharmony_ci  // process.execPath
2261cb0ef41Sopenharmony_ci  process
2271cb0ef41Sopenharmony_ci      ->Set(context,
2281cb0ef41Sopenharmony_ci            FIXED_ONE_BYTE_STRING(isolate, "execPath"),
2291cb0ef41Sopenharmony_ci            String::NewFromUtf8(isolate,
2301cb0ef41Sopenharmony_ci                                env->exec_path().c_str(),
2311cb0ef41Sopenharmony_ci                                NewStringType::kInternalized,
2321cb0ef41Sopenharmony_ci                                env->exec_path().size())
2331cb0ef41Sopenharmony_ci                .ToLocalChecked())
2341cb0ef41Sopenharmony_ci      .Check();
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci  // process.debugPort
2371cb0ef41Sopenharmony_ci  CHECK(process
2381cb0ef41Sopenharmony_ci            ->SetAccessor(context,
2391cb0ef41Sopenharmony_ci                          FIXED_ONE_BYTE_STRING(isolate, "debugPort"),
2401cb0ef41Sopenharmony_ci                          DebugPortGetter,
2411cb0ef41Sopenharmony_ci                          env->owns_process_state() ? DebugPortSetter : nullptr,
2421cb0ef41Sopenharmony_ci                          Local<Value>())
2431cb0ef41Sopenharmony_ci            .FromJust());
2441cb0ef41Sopenharmony_ci}
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_civoid RegisterProcessExternalReferences(ExternalReferenceRegistry* registry) {
2471cb0ef41Sopenharmony_ci  registry->Register(RawDebug);
2481cb0ef41Sopenharmony_ci  registry->Register(GetParentProcessId);
2491cb0ef41Sopenharmony_ci  registry->Register(DebugPortSetter);
2501cb0ef41Sopenharmony_ci  registry->Register(DebugPortGetter);
2511cb0ef41Sopenharmony_ci  registry->Register(ProcessTitleSetter);
2521cb0ef41Sopenharmony_ci  registry->Register(ProcessTitleGetter);
2531cb0ef41Sopenharmony_ci}
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci}  // namespace node
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ciNODE_BINDING_EXTERNAL_REFERENCE(process_object,
2581cb0ef41Sopenharmony_ci                                node::RegisterProcessExternalReferences)
259