| 302 | } |
| 303 | |
| 304 | function unwrapJSONLikeSource(source, options) { |
| 305 | options = options || {}; |
| 306 | source = String(source || '').trim(); |
| 307 | let fnTry = null; |
| 308 | let fnCatch = null; |
| 309 | let funcName = null; |
| 310 | |
| 311 | if (options.allowJSONP === false) { |
| 312 | return { source, funcName, fnTry, fnCatch }; |
| 313 | } |
| 314 | |
| 315 | if (source.startsWith('try {')) { |
| 316 | fnTry = 'try {'; |
| 317 | source = source.slice(5).trimStart(); |
| 318 | } |
| 319 | |
| 320 | const catchIdx = source.lastIndexOf('} catch'); |
| 321 | if (catchIdx !== -1) { |
| 322 | fnCatch = source.slice(catchIdx); |
| 323 | source = source.slice(0, catchIdx).trimEnd(); |
| 324 | } |
| 325 | |
| 326 | const matches = /^([\w\.]+)\(\s*([\s\S]*)\s*\)$/m.exec(source); |
| 327 | if (matches != null && ((fnTry && fnCatch) || (!fnTry && !fnCatch))) { |
| 328 | funcName = matches[1]; |
| 329 | source = matches[2]; |
| 330 | } |
| 331 | |
| 332 | return { source, funcName, fnTry, fnCatch }; |
| 333 | } |
| 334 | |
| 335 | function stripJSONGuards(source) { |
| 336 | source = String(source || '').trim().replace(/^\uFEFF/, ''); |