(text)
| 1802 | // 与 worker 保持一致的 BigInt 安全解析: |
| 1803 | // 1) 给可能的大整数加标记;2) 使用reviver还原为原生BigInt |
| 1804 | let _parseWithBigInt = function(text) { |
| 1805 | if ( |
| 1806 | typeof window !== 'undefined' && |
| 1807 | window.FHJsonAutoUtils && |
| 1808 | typeof window.FHJsonAutoUtils.parseWithBigInt === 'function' |
| 1809 | ) { |
| 1810 | return window.FHJsonAutoUtils.parseWithBigInt(text); |
| 1811 | } |
| 1812 | |
| 1813 | // 先解析JSON,然后在对象层面处理大整数 |
| 1814 | // 这样可以避免在字符串内容中错误地匹配数字 |
| 1815 | try { |
| 1816 | // 直接解析,如果成功则不需要BigInt处理 |
| 1817 | return JSON.parse(text); |
| 1818 | } catch (e) { |
| 1819 | // 如果解析失败,可能是因为大整数导致的精度问题 |
| 1820 | // 使用更安全的方式:只在非字符串上下文中标记大整数 |
| 1821 | // 通过状态机跟踪是否在字符串内部 |
| 1822 | let inString = false; |
| 1823 | let escape = false; |
| 1824 | let marked = ''; |
| 1825 | |
| 1826 | for (let i = 0; i < text.length; i++) { |
| 1827 | const char = text[i]; |
| 1828 | |
| 1829 | if (escape) { |
| 1830 | marked += char; |
| 1831 | escape = false; |
| 1832 | continue; |
| 1833 | } |
| 1834 | |
| 1835 | if (char === '\\') { |
| 1836 | marked += char; |
| 1837 | escape = true; |
| 1838 | continue; |
| 1839 | } |
| 1840 | |
| 1841 | if (char === '"') { |
| 1842 | inString = !inString; |
| 1843 | marked += char; |
| 1844 | continue; |
| 1845 | } |
| 1846 | |
| 1847 | marked += char; |
| 1848 | } |
| 1849 | |
| 1850 | // 只在非字符串上下文中替换大整数 |
| 1851 | // 使用更精确的正则,确保不在字符串内 |
| 1852 | const result = text.replace(/([:,\[]\s*)(-?\d{16,})(\s*)(?=[,\]\}])/g, function(match, prefix, number, spaces, offset) { |
| 1853 | // 检查这个位置是否在字符串内 |
| 1854 | let inStr = false; |
| 1855 | let esc = false; |
| 1856 | for (let i = 0; i < offset; i++) { |
| 1857 | if (esc) { |
| 1858 | esc = false; |
| 1859 | continue; |
| 1860 | } |
| 1861 | if (text[i] === '\\') { |
no test coverage detected