Skip to content

Commit e05079f

Browse files
committed
feat(rtts_assert): avoid deep recursion in prettyPrint
1 parent 908a0aa commit e05079f

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

modules/rtts_assert/src/rtts_assert.es6

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,15 @@ function assertArgumentTypes(...params) {
7474
}
7575
}
7676

77-
function prettyPrint(value) {
77+
function prettyPrint(value, depth) {
78+
if (typeof(depth) === 'undefined') {
79+
depth = 0;
80+
}
81+
82+
if (depth++ > 3) {
83+
return '[...]';
84+
}
85+
7886
if (typeof value === 'undefined') {
7987
return 'undefined';
8088
}
@@ -96,12 +104,17 @@ function prettyPrint(value) {
96104
return value.__assertName;
97105
}
98106

99-
if (value.map) {
100-
return '[' + value.map(prettyPrint).join(', ') + ']';
107+
if (value.map && typeof value.map === 'function') {
108+
return '[' + value.map((v) => prettyPrint(v, depth)).join(', ') + ']';
101109
}
102110

103111
var properties = Object.keys(value);
104-
return '{' + properties.map((p) => p + ': ' + prettyPrint(value[p])).join(', ') + '}';
112+
var suffix = '}';
113+
if (properties.length > 20) {
114+
properties.length = 20;
115+
suffix = ', ... }';
116+
}
117+
return '{' + properties.map((p) => p + ': ' + prettyPrint(value[p], depth)).join(', ') + suffix;
105118
}
106119

107120
return value.__assertName || value.name || value.toString();

modules/rtts_assert/test/rtts_assert_spec.es6

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,33 @@
1414

1515
export function main() {
1616

17+
describe('prettyPrint', () => {
18+
class Type {};
19+
20+
it('should limit the number of printed properties', () => {
21+
var o = {};
22+
for (var i = 0; i < 100; i++) {
23+
o['p_' + i] = i;
24+
}
25+
try {
26+
assert.type(o, Type);
27+
throw 'fail!';
28+
} catch (e) {
29+
expect(e.message.indexOf('p_0')).toBeGreaterThan(-1);
30+
expect(e.message.indexOf('...')).toBeGreaterThan(-1);
31+
expect(e.message.indexOf('p_20')).toBe(-1);
32+
}
33+
});
34+
35+
it('should limit the depth of printed properties', () => {
36+
var o = {l1: {l2: {l3: {l4: {l5: {l6: 'deep'}}}}}};
37+
38+
expect(() => {
39+
assert.type(o, Type);
40+
}).toThrowError('Expected an instance of Type, got {l1: {l2: {l3: {l4: [...]}}}}!');
41+
});
42+
});
43+
1744
// ## Basic Type Check
1845
// By default, `instanceof` is used to check the type.
1946
//

0 commit comments

Comments
 (0)