Skip to content

Commit efbb932

Browse files
committed
make sure properties that throw on their getters are handled properly, some refactoring
1 parent 73558f0 commit efbb932

File tree

2 files changed

+74
-20
lines changed

2 files changed

+74
-20
lines changed

lib/async-json.js

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,6 @@
5252

5353
function stringifyAux(data, callback, errback, key, counter, context) {
5454
switch (typeof data) {
55-
case "undefined":
56-
callback(undefined);
57-
break;
58-
case "string":
59-
case "number":
60-
callback(jsonStringify(data));
61-
break;
62-
case "boolean":
63-
callback(data ? "true" : "false");
64-
break;
6555
case "object":
6656
if (data === null) {
6757
// why is typeof null === "object"?
@@ -74,10 +64,10 @@
7464
}, errback);
7565
} else if (typeof data.toJSON === "function") {
7666
// used by Date and possibly some others.
77-
stringify(data.toJSON(key), callback, errback, key, counter, undefined);
67+
callback(jsonStringify(data.toJSON(key)));
7868
} else if (isPrimitiveConstructor(data.constructor)) {
7969
// horrible, someone used the new String(), new Number(), or new Boolean() syntax.
80-
stringify(data.valueOf(), callback, errback, key, counter, undefined);
70+
callback(jsonStringify(data));
8171
} else if (isArray(data)) {
8272
internalStringifyArray(data, callback, errback, counter);
8373
} else {
@@ -100,11 +90,8 @@
10090
});
10191
}
10292
break;
103-
case "null":
104-
callback("null");
105-
break;
10693
default:
107-
callback(jsonStringify(value));
94+
callback(jsonStringify(data));
10895
break;
10996
}
11097
}
@@ -178,8 +165,12 @@
178165
}
179166

180167
function run(start) {
181-
for (var i = start; step(i); ++i) {
182-
// nothing to do, as step's return value will cause a halt eventually
168+
try {
169+
for (var i = start; step(i); ++i) {
170+
// nothing to do, as step's return value will cause a halt eventually
171+
}
172+
} catch (e) {
173+
errback(e);
183174
}
184175
}
185176

@@ -254,8 +245,12 @@
254245
};
255246

256247
function run(start) {
257-
for (var i = start; step(i); ++i) {
258-
// nothing to do, as step's return value will cause a halt eventually
248+
try {
249+
for (var i = start; step(i); ++i) {
250+
// nothing to do, as step's return value will cause a halt eventually
251+
}
252+
} catch (e) {
253+
errback(e);
259254
}
260255
};
261256

test/async-json.test.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,56 @@ module.exports = {
188188
}
189189
}));
190190
},
191+
"object with tainted property": Object.defineProperty ? function(beforeExit) {
192+
var obj = {};
193+
var error = new Error();
194+
Object.defineProperty(obj, 'key', {
195+
get: function () {
196+
throw error;
197+
},
198+
enumerable: true
199+
})
200+
var calls = 0;
201+
202+
asyncJSON.stringify(obj, function (err) {
203+
assert.strictEqual(error, err);
204+
++calls;
205+
});
206+
207+
beforeExit(function() {
208+
assert.strictEqual(1, calls);
209+
});
210+
} : null,
211+
"object with tainted property after async": Object.defineProperty ? function(beforeExit) {
212+
var obj = {
213+
init: function (callback) {
214+
process.nextTick(function () {
215+
try {
216+
callback(null, 'value');
217+
} catch (e) {
218+
throw new Error("should not reach here");
219+
}
220+
});
221+
}
222+
};
223+
var error = new Error();
224+
Object.defineProperty(obj, 'key', {
225+
get: function () {
226+
throw error;
227+
},
228+
enumerable: true
229+
})
230+
var calls = 0;
231+
232+
asyncJSON.stringify(obj, function (err) {
233+
assert.strictEqual(error, err);
234+
++calls;
235+
});
236+
237+
beforeExit(function() {
238+
assert.strictEqual(1, calls);
239+
});
240+
} : null,
191241
"lazy functions": function(beforeExit) {
192242
asyncEquality(beforeExit, function() {
193243
assert.equal(DEFAULT_THIS, this);
@@ -441,5 +491,14 @@ module.exports = {
441491
beforeExit(function() {
442492
assert.strictEqual(1, calls);
443493
});
494+
} : null,
495+
"symbols are ignored as keys": typeof Symbol === 'function' ? function(beforeExit) {
496+
var obj = {};
497+
obj[Symbol('key')] = 'value';
498+
asyncEqualityToSync(beforeExit, obj);
499+
} : null,
500+
"symbols are ignored as keys": typeof Symbol === 'function' ? function(beforeExit) {
501+
var obj = { key: Symbol('value') };
502+
asyncEqualityToSync(beforeExit, obj);
444503
} : null
445504
};

0 commit comments

Comments
 (0)