|
1 | 1 | import assertString from './util/assertString'; |
2 | 2 | import isBase64 from './isBase64'; |
3 | 3 |
|
| 4 | +function decodeBase64Url(b64) { |
| 5 | + if (typeof Buffer !== 'undefined') { |
| 6 | + if (typeof Buffer.from === 'function') { |
| 7 | + return Buffer.from(b64, 'base64').toString('utf8'); |
| 8 | + } |
| 9 | + // eslint-disable-next-line no-buffer-constructor |
| 10 | + return new Buffer(b64, 'base64').toString('utf8'); |
| 11 | + } |
| 12 | + if (typeof atob === 'function') { |
| 13 | + const binary = atob(b64); |
| 14 | + if (typeof TextDecoder !== 'undefined') { |
| 15 | + const bytes = new Uint8Array(binary.length); |
| 16 | + for (let i = 0; i < binary.length; i += 1) { |
| 17 | + bytes[i] = binary.charCodeAt(i); |
| 18 | + } |
| 19 | + return new TextDecoder('utf-8').decode(bytes); |
| 20 | + } |
| 21 | + let encoded = ''; |
| 22 | + for (let i = 0; i < binary.length; i += 1) { |
| 23 | + const code = binary.charCodeAt(i).toString(16).padStart(2, '0'); |
| 24 | + encoded += `%${code}`; |
| 25 | + } |
| 26 | + return decodeURIComponent(encoded); |
| 27 | + } |
| 28 | + return b64; |
| 29 | +} |
| 30 | + |
4 | 31 | function tryDecodeJSON(segment) { |
5 | 32 | if (!isBase64(segment, { urlSafe: true })) return false; |
6 | 33 | try { |
7 | 34 | // Normalize base64url alphabet to base64, then restore stripped padding |
8 | 35 | let b64 = segment.replace(/-/g, '+').replace(/_/g, '/'); |
9 | 36 | while (b64.length % 4) b64 += '='; |
10 | | - const decoded = Buffer.from(b64, 'base64').toString('utf8'); |
| 37 | + const decoded = decodeBase64Url(b64); |
11 | 38 | const parsed = JSON.parse(decoded); |
12 | 39 | if (typeof parsed !== 'object') return false; |
13 | 40 | if (parsed === null) return false; |
|
0 commit comments