Avoid infinite recursion in Error.prepareStackTrace

Previously, prepareStackTraceWithStackAssignment could end up calling
itself when third-party code assigned Error.prepareStackTrace back
to its original value. Now, we short-circuit this process if the
rawStack property has already been assigned.

Signed-off-by: Max Brunsfeld <maxbrunsfeld@github.com>
This commit is contained in:
Nathan Sobo 2015-11-30 10:47:40 -08:00
parent 228e67838c
commit f139992585
2 changed files with 28 additions and 3 deletions

View File

@ -81,6 +81,27 @@ describe 'CompileCache', ->
waits(1)
runs ->
error = new Error("Oops again")
console.log error.stack
expect(error.stack).toContain('compile-cache-spec.coffee')
expect(Array.isArray(error.getRawStack())).toBe true
it 'does not infinitely loop when the original prepareStackTrace value is reassigned', ->
originalPrepareStackTrace = Error.prepareStackTrace
Error.prepareStackTrace = -> 'a-stack-trace'
Error.prepareStackTrace = originalPrepareStackTrace
error = new Error('Oops')
expect(error.stack).toContain('compile-cache-spec.coffee')
expect(Array.isArray(error.getRawStack())).toBe true
it 'does not infinitely loop when the assigned prepareStackTrace calls the original prepareStackTrace', ->
originalPrepareStackTrace = Error.prepareStackTrace
Error.prepareStackTrace = (error, stack) ->
error.foo = 'bar'
originalPrepareStackTrace(error, stack)
error = new Error('Oops')
expect(error.stack).toContain('compile-cache-spec.coffee')
expect(error.foo).toBe('bar')
expect(Array.isArray(error.getRawStack())).toBe true

View File

@ -163,8 +163,12 @@ var prepareStackTraceWithSourceMapping = Error.prepareStackTrace
let prepareStackTrace = prepareStackTraceWithSourceMapping
function prepareStackTraceWithRawStackAssignment (error, frames) {
error.rawStack = frames
return prepareStackTrace(error, frames)
if (error.rawStack) { // avoid infinite recursion
return prepareStackTraceWithSourceMapping(error, frames)
} else {
error.rawStack = frames
return prepareStackTrace(error, frames)
}
}
Object.defineProperty(Error, 'prepareStackTrace', {