|
30 | 30 |
|
31 | 31 | const queryStringRegex = /\?.*$/ |
32 | 32 |
|
| 33 | + let hasValidCallbackContext = false |
| 34 | + |
33 | 35 | // since this function is eval'd, the scripts are included as stringified JSON |
34 | 36 | if (scripts) { |
35 | 37 | scripts = parse(scripts) |
|
69 | 71 | return filteredLines.length > 0 |
70 | 72 | } |
71 | 73 |
|
| 74 | + const isInCallback = (err) => { |
| 75 | + return stringIncludes.call(err.stack, 'thenFn@') || stringIncludes.call(err.stack, 'withinFn@') |
| 76 | + } |
| 77 | + |
| 78 | + const hasCallbackInsideEval = (err) => { |
| 79 | + if (browserFamily === 'webkit') { |
| 80 | + return isInCallback(err) && hasValidCallbackContext |
| 81 | + } |
| 82 | + |
| 83 | + return isInCallback(err) && stringIncludes.call(err.stack, '> eval line') |
| 84 | + } |
| 85 | + |
72 | 86 | // in non-chromium browsers, the stack will include either the spec file url |
73 | 87 | // or the support file |
74 | 88 | const hasStackLinesFromSpecOrSupportFile = (err) => { |
|
96 | 110 | 'task', |
97 | 111 | ] |
98 | 112 |
|
| 113 | + const callbackCommands = [ |
| 114 | + 'each', |
| 115 | + 'then', |
| 116 | + 'within', |
| 117 | + ] |
| 118 | + |
99 | 119 | function stackIsFromSpecFrame (err) { |
100 | 120 | if (isSpecBridge) { |
101 | 121 | return hasSpecBridgeInvocation(err) |
102 | 122 | } |
103 | 123 |
|
104 | 124 | if (browserFamily === 'chromium') { |
105 | | - return hasSpecFrameStackLines(err) |
| 125 | + return hasStackLinesFromSpecOrSupportFile(err) || hasSpecFrameStackLines(err) |
106 | 126 | } |
107 | 127 |
|
108 | | - return hasStackLinesFromSpecOrSupportFile(err) |
| 128 | + return hasCallbackInsideEval(err) || hasStackLinesFromSpecOrSupportFile(err) |
109 | 129 | } |
110 | 130 |
|
111 | 131 | // source: https://github.com/bryc/code/blob/d0dac1c607a005679799024ff66166e13601d397/jshash/experimental/cyrb53.js |
|
141 | 161 | } |
142 | 162 |
|
143 | 163 | async function onCommandInvocation (command) { |
144 | | - if (!arrayIncludes.call(privilegedCommands, command.name)) return |
145 | | - |
146 | 164 | // message doesn't really matter since we're only interested in the stack |
147 | 165 | const err = new Err('command stack error') |
148 | 166 |
|
|
152 | 170 | captureStackTrace.call(Err, err, onCommandInvocation) |
153 | 171 | } |
154 | 172 |
|
| 173 | + if (arrayIncludes.call(callbackCommands, command.name)) { |
| 174 | + hasValidCallbackContext = stackIsFromSpecFrame(err) |
| 175 | + } |
| 176 | + |
| 177 | + if (!arrayIncludes.call(privilegedCommands, command.name)) return |
| 178 | + |
155 | 179 | // if stack is not validated as being from the spec frame, don't add |
156 | 180 | // it as a verified command |
157 | 181 | if (!stackIsFromSpecFrame(err)) return |
|
0 commit comments