|
223 | 223 | * @param {Object} value |
224 | 224 | * @param {Function} [replacer] |
225 | 225 | * @param {(Number|String)} [space] |
| 226 | + * @param {Object} [options] |
226 | 227 | * @return {String} |
227 | 228 | */ |
228 | | - return function (value, replacer, space) { |
| 229 | + return function (value, replacer, space, options) { |
| 230 | + options = options || {} |
| 231 | + |
229 | 232 | // Convert the spaces into a string. |
230 | 233 | if (typeof space !== 'string') { |
231 | 234 | space = new Array(Math.max(0, space|0) + 1).join(' '); |
232 | 235 | } |
233 | 236 |
|
| 237 | + var maxDepth = options.maxDepth || 200; |
| 238 | + |
| 239 | + var depth = 0; |
| 240 | + var cache = []; |
| 241 | + |
234 | 242 | /** |
235 | 243 | * Handle recursion by checking if we've visited this node every iteration. |
236 | 244 | * |
237 | 245 | * @param {*} value |
238 | | - * @param {Array} cache |
239 | 246 | * @return {String} |
240 | 247 | */ |
241 | | - var recurse = function (value, cache, next) { |
| 248 | + var recurse = function (value, next) { |
242 | 249 | // If we've already visited this node before, break the recursion. |
243 | | - if (cache.indexOf(value) > -1) { |
| 250 | + if (cache.indexOf(value) > -1 || depth > maxDepth) { |
244 | 251 | return; |
245 | 252 | } |
246 | 253 |
|
247 | 254 | // Push the value into the values cache to avoid an infinite loop. |
| 255 | + depth++; |
248 | 256 | cache.push(value); |
249 | 257 |
|
250 | 258 | // Stringify the value and fallback to |
251 | 259 | return next(value, space, function (value) { |
252 | | - return recurse(value, cache.slice(), next); |
| 260 | + var result = recurse(value, next); |
| 261 | + |
| 262 | + depth--; |
| 263 | + cache.pop(); |
| 264 | + |
| 265 | + return result; |
253 | 266 | }); |
254 | 267 | }; |
255 | 268 |
|
256 | 269 | // If the user defined a replacer function, make the recursion function |
257 | 270 | // a double step process - `replacer -> stringify -> replacer -> etc`. |
258 | 271 | if (typeof replacer === 'function') { |
259 | | - return recurse(value, [], function (value, space, next) { |
| 272 | + return recurse(value, function (value, space, next) { |
260 | 273 | return replacer(value, space, function (value) { |
261 | 274 | return stringify(value, space, next); |
262 | 275 | }); |
263 | 276 | }); |
264 | 277 | } |
265 | 278 |
|
266 | | - return recurse(value, [], stringify); |
| 279 | + return recurse(value, stringify); |
267 | 280 | }; |
268 | 281 | }); |
0 commit comments