Skip to content

Commit c8239c0

Browse files
author
Julien Gilli
committed
console: allow Object.prototype fields as labels
This is a backport of 6c3647c from v0.12 to v0.10. Console.prototype.timeEnd() returns NaN if the timer label corresponds to a property on Object.prototype. In v0.12, this was fixed by using Object.create(null) to construct the _times object However, the version of V8 in the v0.10 branch makes this fix not work as expected. In v0.10, this commit changes the _times object into a array of objects of the form: { label: someLabel, time: staringWallClockTime } someLabel can thus be any string, including any string that represents any Object.prototype field. Fixes #9116. PR: #9215 PR-URL: nodejs/node-v0.x-archive#9215 Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent ad06848 commit c8239c0

File tree

2 files changed

+55
-15
lines changed

2 files changed

+55
-15
lines changed

lib/console.js

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
var util = require('util');
23+
var assert = require('assert');
2324

2425
function Console(stdout, stderr) {
2526
if (!(this instanceof Console)) {
@@ -40,7 +41,7 @@ function Console(stdout, stderr) {
4041
Object.defineProperty(this, '_stdout', prop);
4142
prop.value = stderr;
4243
Object.defineProperty(this, '_stderr', prop);
43-
prop.value = {};
44+
prop.value = [];
4445
Object.defineProperty(this, '_times', prop);
4546

4647
// bind the prototype functions to this Console instance
@@ -70,18 +71,44 @@ Console.prototype.dir = function(object) {
7071
};
7172

7273

74+
function findTimeWithLabel(times, label) {
75+
assert(Array.isArray(times), 'times must be an Array');
76+
assert(typeof label === 'string', 'label must be a string');
77+
78+
var found;
79+
80+
times.some(function findTime(item) {
81+
if (item.label === label) {
82+
found = item;
83+
return true;
84+
}
85+
});
86+
87+
return found;
88+
}
89+
7390
Console.prototype.time = function(label) {
74-
this._times[label] = Date.now();
91+
var timeEntry = findTimeWithLabel(this._times, label);
92+
var wallClockTime = Date.now();
93+
if (!timeEntry) {
94+
this._times.push({ label: label, time: wallClockTime });
95+
} else {
96+
timeEntry.time = wallClockTime;
97+
}
7598
};
7699

77-
78100
Console.prototype.timeEnd = function(label) {
79-
var time = this._times[label];
80-
if (!time) {
101+
var wallClockTimeEnd = Date.now();
102+
var timeEntry = findTimeWithLabel(this._times, label);
103+
104+
if (!timeEntry) {
81105
throw new Error('No such label: ' + label);
106+
} else {
107+
assert(typeof timeEntry.time === 'number',
108+
'start time must be a number');
109+
var duration = wallClockTimeEnd - timeEntry.time;
110+
this.log('%s: %dms', label, duration);
82111
}
83-
var duration = Date.now() - time;
84-
this.log('%s: %dms', label, duration);
85112
};
86113

87114

test/simple/test-console.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,22 @@ console.log({slashes: '\\\\'});
4646
console._stderr = process.stdout;
4747
console.trace('This is a %j %d', { formatted: 'trace' }, 10, 'foo');
4848

49+
assert.throws(function () {
50+
console.timeEnd('no such label');
51+
});
52+
53+
assert.doesNotThrow(function () {
54+
console.time('label');
55+
console.timeEnd('label');
56+
});
57+
58+
console.time('__proto__');
59+
console.timeEnd('__proto__');
60+
console.time('constructor');
61+
console.timeEnd('constructor');
62+
console.time('hasOwnProperty');
63+
console.timeEnd('hasOwnProperty');
64+
4965
global.process.stdout.write = stdout_write;
5066

5167
assert.equal('foo\n', strings.shift());
@@ -55,11 +71,8 @@ assert.equal("{ slashes: '\\\\\\\\' }\n", strings.shift());
5571
assert.equal('Trace: This is a {"formatted":"trace"} 10 foo',
5672
strings.shift().split('\n').shift());
5773

58-
assert.throws(function () {
59-
console.timeEnd('no such label');
60-
});
61-
62-
assert.doesNotThrow(function () {
63-
console.time('label');
64-
console.timeEnd('label');
65-
});
74+
assert.ok(/^label: \d+ms$/.test(strings.shift().trim()));
75+
assert.ok(/^__proto__: \d+ms$/.test(strings.shift().trim()));
76+
assert.ok(/^constructor: \d+ms$/.test(strings.shift().trim()));
77+
assert.ok(/^hasOwnProperty: \d+ms$/.test(strings.shift().trim()));
78+
assert.equal(strings.length, 0);

0 commit comments

Comments
 (0)