Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: move more version computation code into node_metadata.cc #25115

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ function startup() {
// Do this good and early, since it handles errors.
setupProcessFatal();

setupProcessICUVersions();

setupGlobalVariables();

// Bootstrappers for all threads, including worker threads and main thread
Expand Down Expand Up @@ -638,25 +636,6 @@ function setupProcessFatal() {
};
}

function setupProcessICUVersions() {
const icu = internalBinding('config').hasIntl ?
internalBinding('icu') : undefined;
if (!icu) return; // no Intl/ICU: nothing to add here.
// With no argument, getVersion() returns a comma separated list
// of possible types.
const versionTypes = icu.getVersion().split(',');

for (var n = 0; n < versionTypes.length; n++) {
const name = versionTypes[n];
const version = icu.getVersion(name);
Object.defineProperty(process.versions, name, {
writable: false,
enumerable: true,
value: version
});
}
}

function wrapForBreakOnFirstLine(source) {
if (!process._breakFirstLine)
return source;
Expand Down
6 changes: 5 additions & 1 deletion src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,10 @@ void SetupProcessObject(Environment* env,
READONLY_PROPERTY(process, "versions", versions);

#define V(key) \
READONLY_STRING_PROPERTY(versions, #key, per_process::metadata.versions.key);
if (!per_process::metadata.versions.key.empty()) { \
READONLY_STRING_PROPERTY( \
versions, #key, per_process::metadata.versions.key); \
}
NODE_VERSIONS_KEYS(V)
#undef V

Expand Down Expand Up @@ -1664,6 +1667,7 @@ void Init(std::vector<std::string>* argv,
argv->at(0).c_str());
exit(9);
}
per_process::metadata.versions.InitializeIntlVersions();
#endif

// We should set node_is_initialized here instead of in node::Start,
Expand Down
15 changes: 0 additions & 15 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5842,21 +5842,6 @@ void Initialize(Local<Object> target,
#endif // OPENSSL_NO_SCRYPT
}

constexpr int search(const char* s, int n, int c) {
return *s == c ? n : search(s + 1, n + 1, c);
}

std::string GetOpenSSLVersion() {
// sample openssl version string format
// for reference: "OpenSSL 1.1.0i 14 Aug 2018"
char buf[128];
const int start = search(OPENSSL_VERSION_TEXT, 0, ' ') + 1;
const int end = search(OPENSSL_VERSION_TEXT + start, start, ' ');
const int len = end - start;
snprintf(buf, sizeof(buf), "%.*s", len, &OPENSSL_VERSION_TEXT[start]);
return std::string(buf);
}

} // namespace crypto
} // namespace node

Expand Down
1 change: 0 additions & 1 deletion src/node_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ extern int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx);
extern void UseExtraCaCerts(const std::string& file);

void InitCryptoOnce();
std::string GetOpenSSLVersion();

class SecureContext : public BaseObject {
public:
Expand Down
4 changes: 3 additions & 1 deletion src/node_http_parser_llhttp.cc
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
#define NODE_EXPERIMENTAL_HTTP 1

#include "node_http_parser_impl.h"
#include "node_metadata.h"

namespace node {

namespace per_process {
const char* const llhttp_version =
NODE_STRINGIFY(LLHTTP_VERSION_MAJOR)
"."
NODE_STRINGIFY(LLHTTP_VERSION_MINOR)
"."
NODE_STRINGIFY(LLHTTP_VERSION_PATCH);

} // namespace per_process
} // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(http_parser_llhttp,
Expand Down
5 changes: 3 additions & 2 deletions src/node_http_parser_traditional.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
#endif

#include "node_http_parser_impl.h"
#include "node_metadata.h"

namespace node {

namespace per_process {
const char* const http_parser_version =
NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
"."
NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
"."
NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);

} // namespace per_process
} // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(http_parser, node::InitializeHttpParser)
62 changes: 0 additions & 62 deletions src/node_i18n.cc
Original file line number Diff line number Diff line change
Expand Up @@ -510,67 +510,6 @@ void ICUErrorName(const FunctionCallbackInfo<Value>& args) {
NewStringType::kNormal).ToLocalChecked());
}

#define TYPE_ICU "icu"
#define TYPE_UNICODE "unicode"
#define TYPE_CLDR "cldr"
#define TYPE_TZ "tz"

/**
* This is the workhorse function that deals with the actual version info.
* Get an ICU version.
* @param type the type of version to get. One of VERSION_TYPES
* @param buf optional buffer for result
* @param status ICU error status. If failure, assume result is undefined.
* @return version number, or NULL. May or may not be buf.
*/
const char* GetVersion(const char* type,
joyeecheung marked this conversation as resolved.
Show resolved Hide resolved
char buf[U_MAX_VERSION_STRING_LENGTH],
UErrorCode* status) {
if (!strcmp(type, TYPE_ICU)) {
return U_ICU_VERSION;
} else if (!strcmp(type, TYPE_UNICODE)) {
return U_UNICODE_VERSION;
} else if (!strcmp(type, TYPE_TZ)) {
return icu::TimeZone::getTZDataVersion(*status);
} else if (!strcmp(type, TYPE_CLDR)) {
UVersionInfo versionArray;
ulocdata_getCLDRVersion(versionArray, status);
if (U_SUCCESS(*status)) {
u_versionToString(versionArray, buf);
return buf;
}
}
// Fall through - unknown type or error case
return nullptr;
}

void GetVersion(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
if ( args.Length() == 0 ) {
// With no args - return a comma-separated list of allowed values
args.GetReturnValue().Set(
String::NewFromUtf8(env->isolate(),
TYPE_ICU ","
TYPE_UNICODE ","
TYPE_CLDR ","
TYPE_TZ, NewStringType::kNormal).ToLocalChecked());
} else {
CHECK_GE(args.Length(), 1);
CHECK(args[0]->IsString());
Utf8Value val(env->isolate(), args[0]);
UErrorCode status = U_ZERO_ERROR;
char buf[U_MAX_VERSION_STRING_LENGTH] = ""; // Possible output buffer.
const char* versionString = GetVersion(*val, buf, &status);

if (U_SUCCESS(status) && versionString) {
// Success.
args.GetReturnValue().Set(
String::NewFromUtf8(env->isolate(),
versionString, NewStringType::kNormal).ToLocalChecked());
}
}
}

} // anonymous namespace

bool InitializeICUDirectory(const std::string& path) {
Expand Down Expand Up @@ -868,7 +807,6 @@ void Initialize(Local<Object> target,
env->SetMethod(target, "toUnicode", ToUnicode);
env->SetMethod(target, "toASCII", ToASCII);
env->SetMethod(target, "getStringWidth", GetStringWidth);
env->SetMethod(target, "getVersion", GetVersion);

// One-shot converters
env->SetMethod(target, "icuErrName", ICUErrorName);
Expand Down
3 changes: 0 additions & 3 deletions src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -698,9 +698,6 @@ static inline const char* errno_string(int errorno) {

extern double prog_start_time;

extern const char* const llhttp_version;
extern const char* const http_parser_version;

void Abort(const v8::FunctionCallbackInfo<v8::Value>& args);
void Chdir(const v8::FunctionCallbackInfo<v8::Value>& args);
void CPUUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
Expand Down
59 changes: 53 additions & 6 deletions src/node_metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,64 @@
#include "ares.h"
#include "nghttp2/nghttp2ver.h"
#include "node.h"
#include "node_internals.h"
#include "util.h"
#include "uv.h"
#include "v8.h"
#include "zlib.h"

#if HAVE_OPENSSL
#include "node_crypto.h"
#endif
#include <openssl/opensslv.h>
#endif // HAVE_OPENSSL

#ifdef NODE_HAVE_I18N_SUPPORT
#include <unicode/timezone.h>
#include <unicode/ulocdata.h>
#include <unicode/uvernum.h>
#include <unicode/uversion.h>
#endif // NODE_HAVE_I18N_SUPPORT

namespace node {

namespace per_process {
Metadata metadata;
}

#if HAVE_OPENSSL
constexpr int search(const char* s, int n, int c) {
return *s == c ? n : search(s + 1, n + 1, c);
}

std::string GetOpenSSLVersion() {
// sample openssl version string format
// for reference: "OpenSSL 1.1.0i 14 Aug 2018"
char buf[128];
const int start = search(OPENSSL_VERSION_TEXT, 0, ' ') + 1;
const int end = search(OPENSSL_VERSION_TEXT + start, start, ' ');
const int len = end - start;
snprintf(buf, sizeof(buf), "%.*s", len, &OPENSSL_VERSION_TEXT[start]);
return std::string(buf);
}
#endif // HAVE_OPENSSL

#ifdef NODE_HAVE_I18N_SUPPORT
void Metadata::Versions::InitializeIntlVersions() {
UErrorCode status = U_ZERO_ERROR;

const char* tz_version = icu::TimeZone::getTZDataVersion(status);
if (U_SUCCESS(status)) {
tz = tz_version;
}

char buf[U_MAX_VERSION_STRING_LENGTH];
UVersionInfo versionArray;
ulocdata_getCLDRVersion(versionArray, &status);
if (U_SUCCESS(status)) {
u_versionToString(versionArray, buf);
cldr = buf;
}
}
#endif // NODE_HAVE_I18N_SUPPORT

Metadata::Versions::Versions() {
node = NODE_VERSION_STRING;
v8 = v8::V8::GetVersion();
Expand All @@ -27,12 +69,17 @@ Metadata::Versions::Versions() {
modules = NODE_STRINGIFY(NODE_MODULE_VERSION);
nghttp2 = NGHTTP2_VERSION;
napi = NODE_STRINGIFY(NAPI_VERSION);
llhttp = llhttp_version;
http_parser = http_parser_version;
llhttp = per_process::llhttp_version;
http_parser = per_process::http_parser_version;

#if HAVE_OPENSSL
openssl = crypto::GetOpenSSLVersion();
openssl = GetOpenSSLVersion();
#endif

#ifdef NODE_HAVE_I18N_SUPPORT
icu = U_ICU_VERSION;
unicode = U_UNICODE_VERSION;
#endif // NODE_HAVE_I18N_SUPPORT
}

} // namespace node
28 changes: 27 additions & 1 deletion src/node_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,38 @@ namespace node {
#define NODE_VERSIONS_KEY_CRYPTO(V)
#endif

#ifdef NODE_HAVE_I18N_SUPPORT
#define NODE_VERSIONS_KEY_INTL(V) \
V(cldr) \
V(icu) \
V(tz) \
V(unicode)
#else
#define NODE_VERSIONS_KEY_INTL(V)
#endif // NODE_HAVE_I18N_SUPPORT

#define NODE_VERSIONS_KEYS(V) \
NODE_VERSIONS_KEYS_BASE(V) \
NODE_VERSIONS_KEY_CRYPTO(V)
NODE_VERSIONS_KEY_CRYPTO(V) \
NODE_VERSIONS_KEY_INTL(V)

class Metadata {
public:
Metadata() = default;
Metadata(Metadata&) = delete;
Metadata(Metadata&&) = delete;
Metadata operator=(Metadata&) = delete;
Metadata operator=(Metadata&&) = delete;

struct Versions {
Versions();

#ifdef NODE_HAVE_I18N_SUPPORT
// Must be called on the main thread after
// i18n::InitializeICUDirectory()
void InitializeIntlVersions();
#endif // NODE_HAVE_I18N_SUPPORT

#define V(key) std::string key;
NODE_VERSIONS_KEYS(V)
#undef V
Expand All @@ -44,6 +68,8 @@ class Metadata {
// Per-process global
namespace per_process {
extern Metadata metadata;
extern const char* const llhttp_version;
extern const char* const http_parser_version;
}

} // namespace node
Expand Down