Skip to content
This repository was archived by the owner on Jun 18, 2021. It is now read-only.

Commit a30d76d

Browse files
committed
Get Node.js version from process.versions
If process.version is not available obtain the Node.js version from process.versions if available.
1 parent a75db7f commit a30d76d

File tree

3 files changed

+61
-21
lines changed

3 files changed

+61
-21
lines changed

src/node_report.cc

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
#define NODEREPORT_VERSION "dev"
3838
#endif
3939

40+
#if !defined(UNKNOWN_NODEVERSION_STRING)
41+
#define UNKNOWN_NODEVERSION_STRING "Unable to determine Node.js version\n"
42+
#endif
43+
4044
#ifndef _WIN32
4145
extern char** environ;
4246
#endif
@@ -72,7 +76,7 @@ const char* v8_states[] = {"JS", "GC", "COMPILER", "OTHER", "EXTERNAL", "IDLE"};
7276
static bool report_active = false; // recursion protection
7377
static char report_filename[NR_MAXNAME + 1] = "";
7478
static char report_directory[NR_MAXPATH + 1] = ""; // defaults to current working directory
75-
static std::string version_string = "Unable to determine Node.js version\n";
79+
static std::string version_string = UNKNOWN_NODEVERSION_STRING;
7680
#ifdef _WIN32
7781
static SYSTEMTIME loadtime_tm_struct; // module load time
7882
#else // UNIX, OSX
@@ -195,6 +199,7 @@ unsigned int ProcessNodeReportVerboseSwitch(const char* args) {
195199
void SetVersionString(Isolate* isolate) {
196200
// Catch anything thrown and gracefully return
197201
Nan::TryCatch trycatch;
202+
version_string = UNKNOWN_NODEVERSION_STRING;
198203

199204
// Retrieve the process object
200205
v8::Local<v8::String> process_prop;
@@ -209,20 +214,21 @@ void SetVersionString(Isolate* isolate) {
209214
if (!Nan::New<v8::String>("version").ToLocal(&version_prop)) return;
210215
v8::Local<v8::Value> version;
211216
if (!Nan::Get(process_obj, version_prop).ToLocal(&version)) return;
212-
if (!version->IsString()) return;
213217

214-
// Format Node.js version for output in report
215218
// e.g. Node.js version: v6.9.1
216-
Nan::Utf8String node_version(version);
217-
version_string.assign("Node.js version: ");
218-
version_string.append(*node_version);
219-
version_string.append("\n");
219+
if (version->IsString()) {
220+
Nan::Utf8String node_version(version);
221+
version_string = "Node.js version: ";
222+
version_string += *node_version;
223+
version_string += "\n";
224+
}
220225

221226
// Get process.versions
222227
v8::Local<v8::String> versions_prop;
223228
if (!Nan::New<v8::String>("versions").ToLocal(&versions_prop)) return;
224229
v8::Local<v8::Value> versions_value;
225230
if (!Nan::Get(process_obj, versions_prop).ToLocal(&versions_value)) return;
231+
if (!versions_value->IsObject()) return;
226232
v8::Local<v8::Object> versions_obj = versions_value.As<v8::Object>();
227233

228234
// Get component names and versions from process.versions
@@ -239,14 +245,21 @@ void SetVersionString(Isolate* isolate) {
239245
if (!Nan::Get(versions_obj, name_value).ToLocal(&version_value)) continue;
240246

241247
Nan::Utf8String component_name(name_value);
242-
// Don't duplicate the Node.js version
243-
if (!strcmp("node", *component_name)) continue;
244-
245248
Nan::Utf8String component_version(version_value);
246-
std::string component_version_string(*component_name);
247-
component_version_string.append(": ");
248-
component_version_string.append(*component_version);
249-
comp_versions.push_back(component_version_string);
249+
250+
// Don't duplicate the Node.js version
251+
if (!strcmp("node", *component_name)) {
252+
if (version_string == UNKNOWN_NODEVERSION_STRING) {
253+
version_string = "Node.js version: v";
254+
version_string += *component_version;
255+
version_string += "\n";
256+
}
257+
} else {
258+
std::string component_version_string(*component_name);
259+
component_version_string += ": ";
260+
component_version_string += *component_version;
261+
comp_versions.push_back(component_version_string);
262+
}
250263
}
251264

252265
// Format sorted component versions surrounded by (), wrapped
@@ -255,22 +268,22 @@ void SetVersionString(Isolate* isolate) {
255268
// openssl: 1.0.2j, uv: 1.9.1, v8: 5.1.281.84, zlib: 1.2.8)
256269
const size_t wrap = 80;
257270
size_t line_length = 1;
258-
version_string.append("(");
271+
version_string += "(";
259272
std::sort(comp_versions.begin(), comp_versions.end());
260273
for (auto it = comp_versions.begin(); it != comp_versions.end(); ++it) {
261274
size_t length = (*it).length();
262275
if (line_length + length + 1 >= wrap) {
263-
version_string.append("\n ");
276+
version_string += "\n ";
264277
line_length = 1;
265278
}
266-
version_string.append(*it);
279+
version_string += *it;
267280
line_length += length;
268281
if (it + 1 != comp_versions.end()) {
269-
version_string.append(", ");
282+
version_string += ", ";
270283
line_length += 2;
271284
}
272285
}
273-
version_string.append(")\n");
286+
version_string += ")\n";
274287
}
275288

276289
/*******************************************************************************

test/test-api-bad-processversion.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ if (process.argv[2] === 'child') {
1818
const reports = common.findReports(child.pid);
1919
tap.equal(reports.length, 1, 'Found reports ' + reports);
2020
const report = reports[0];
21-
const validateOpts = { pid: child.pid, expectNodeVersion: false,
22-
expectedVersions: [] };
21+
const validateOpts = { pid: child.pid, expectNodeVersion: true };
2322
common.validate(tap, report, validateOpts);
2423
});
2524
}

test/test-api-noversioninfo.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
3+
// Testcase to check NodeReport succeeds if both process.version and
4+
// process.versions are damaged
5+
if (process.argv[2] === 'child') {
6+
// Tamper with the process object
7+
delete process['version'];
8+
delete process['versions'];
9+
10+
const nodereport = require('../');
11+
nodereport.triggerReport();
12+
} else {
13+
const common = require('./common.js');
14+
const spawn = require('child_process').spawn;
15+
const tap = require('tap');
16+
17+
const child = spawn(process.execPath, [__filename, 'child']);
18+
child.on('exit', (code) => {
19+
tap.plan(3);
20+
tap.equal(code, 0, 'Process exited cleanly');
21+
const reports = common.findReports(child.pid);
22+
tap.equal(reports.length, 1, 'Found reports ' + reports);
23+
const report = reports[0];
24+
const validateOpts = { pid: child.pid, expectNodeVersion: false,
25+
expectedVersions: [] };
26+
common.validate(tap, report, validateOpts);
27+
});
28+
}

0 commit comments

Comments
 (0)