JsonDecoder.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.JsonDecoder = exports.readKey = void 0;
  4. const decodeUtf8_1 = require("@jsonjoy.com/util/lib/buffers/utf8/decodeUtf8");
  5. const Reader_1 = require("@jsonjoy.com/util/lib/buffers/Reader");
  6. const fromBase64Bin_1 = require("@jsonjoy.com/base64/lib/fromBase64Bin");
  7. const util_1 = require("./util");
  8. const REGEX_REPLACE_ESCAPED_CHARS = /\\(b|f|n|r|t|"|\/|\\)/g;
  9. const escapedCharReplacer = (char) => {
  10. switch (char) {
  11. case '\\b':
  12. return '\b';
  13. case '\\f':
  14. return '\f';
  15. case '\\n':
  16. return '\n';
  17. case '\\r':
  18. return '\r';
  19. case '\\t':
  20. return '\t';
  21. case '\\"':
  22. return '"';
  23. case '\\/':
  24. return '/';
  25. case '\\\\':
  26. return '\\';
  27. }
  28. return char;
  29. };
  30. const hasBinaryPrefix = (u8, x) => u8[x] === 0x64 &&
  31. u8[x + 1] === 0x61 &&
  32. u8[x + 2] === 0x74 &&
  33. u8[x + 3] === 0x61 &&
  34. u8[x + 4] === 0x3a &&
  35. u8[x + 5] === 0x61 &&
  36. u8[x + 6] === 0x70 &&
  37. u8[x + 7] === 0x70 &&
  38. u8[x + 8] === 0x6c &&
  39. u8[x + 9] === 0x69 &&
  40. u8[x + 10] === 0x63 &&
  41. u8[x + 11] === 0x61 &&
  42. u8[x + 12] === 0x74 &&
  43. u8[x + 13] === 0x69 &&
  44. u8[x + 14] === 0x6f &&
  45. u8[x + 15] === 0x6e &&
  46. u8[x + 16] === 0x2f &&
  47. u8[x + 17] === 0x6f &&
  48. u8[x + 18] === 0x63 &&
  49. u8[x + 19] === 0x74 &&
  50. u8[x + 20] === 0x65 &&
  51. u8[x + 21] === 0x74 &&
  52. u8[x + 22] === 0x2d &&
  53. u8[x + 23] === 0x73 &&
  54. u8[x + 24] === 0x74 &&
  55. u8[x + 25] === 0x72 &&
  56. u8[x + 26] === 0x65 &&
  57. u8[x + 27] === 0x61 &&
  58. u8[x + 28] === 0x6d &&
  59. u8[x + 29] === 0x3b &&
  60. u8[x + 30] === 0x62 &&
  61. u8[x + 31] === 0x61 &&
  62. u8[x + 32] === 0x73 &&
  63. u8[x + 33] === 0x65 &&
  64. u8[x + 34] === 0x36 &&
  65. u8[x + 35] === 0x34 &&
  66. u8[x + 36] === 0x2c;
  67. const isUndefined = (u8, x) => u8[x++] === 0x61 &&
  68. u8[x++] === 0x74 &&
  69. u8[x++] === 0x61 &&
  70. u8[x++] === 0x3a &&
  71. u8[x++] === 0x61 &&
  72. u8[x++] === 0x70 &&
  73. u8[x++] === 0x70 &&
  74. u8[x++] === 0x6c &&
  75. u8[x++] === 0x69 &&
  76. u8[x++] === 0x63 &&
  77. u8[x++] === 0x61 &&
  78. u8[x++] === 0x74 &&
  79. u8[x++] === 0x69 &&
  80. u8[x++] === 0x6f &&
  81. u8[x++] === 0x6e &&
  82. u8[x++] === 0x2f &&
  83. u8[x++] === 0x63 &&
  84. u8[x++] === 0x62 &&
  85. u8[x++] === 0x6f &&
  86. u8[x++] === 0x72 &&
  87. u8[x++] === 0x2c &&
  88. u8[x++] === 0x62 &&
  89. u8[x++] === 0x61 &&
  90. u8[x++] === 0x73 &&
  91. u8[x++] === 0x65 &&
  92. u8[x++] === 0x36 &&
  93. u8[x++] === 0x34 &&
  94. u8[x++] === 0x3b &&
  95. u8[x++] === 0x39 &&
  96. u8[x++] === 0x77 &&
  97. u8[x++] === 0x3d &&
  98. u8[x++] === 0x3d &&
  99. u8[x++] === 0x22;
  100. const fromCharCode = String.fromCharCode;
  101. const readKey = (reader) => {
  102. const buf = reader.uint8;
  103. const len = buf.length;
  104. const points = [];
  105. let x = reader.x;
  106. let prev = 0;
  107. while (x < len) {
  108. let code = buf[x++];
  109. if ((code & 0x80) === 0) {
  110. if (prev === 92) {
  111. switch (code) {
  112. case 98:
  113. code = 8;
  114. break;
  115. case 102:
  116. code = 12;
  117. break;
  118. case 110:
  119. code = 10;
  120. break;
  121. case 114:
  122. code = 13;
  123. break;
  124. case 116:
  125. code = 9;
  126. break;
  127. case 34:
  128. code = 34;
  129. break;
  130. case 47:
  131. code = 47;
  132. break;
  133. case 92:
  134. code = 92;
  135. break;
  136. default:
  137. throw new Error('Invalid JSON');
  138. }
  139. prev = 0;
  140. }
  141. else {
  142. if (code === 34)
  143. break;
  144. prev = code;
  145. if (prev === 92)
  146. continue;
  147. }
  148. }
  149. else {
  150. const octet2 = buf[x++] & 0x3f;
  151. if ((code & 0xe0) === 0xc0) {
  152. code = ((code & 0x1f) << 6) | octet2;
  153. }
  154. else {
  155. const octet3 = buf[x++] & 0x3f;
  156. if ((code & 0xf0) === 0xe0) {
  157. code = ((code & 0x1f) << 12) | (octet2 << 6) | octet3;
  158. }
  159. else {
  160. if ((code & 0xf8) === 0xf0) {
  161. const octet4 = buf[x++] & 0x3f;
  162. let unit = ((code & 0x07) << 0x12) | (octet2 << 0x0c) | (octet3 << 0x06) | octet4;
  163. if (unit > 0xffff) {
  164. unit -= 0x10000;
  165. const unit0 = ((unit >>> 10) & 0x3ff) | 0xd800;
  166. unit = 0xdc00 | (unit & 0x3ff);
  167. points.push(unit0);
  168. code = unit;
  169. }
  170. else {
  171. code = unit;
  172. }
  173. }
  174. }
  175. }
  176. }
  177. points.push(code);
  178. }
  179. reader.x = x;
  180. return fromCharCode.apply(String, points);
  181. };
  182. exports.readKey = readKey;
  183. class JsonDecoder {
  184. constructor() {
  185. this.reader = new Reader_1.Reader();
  186. }
  187. read(uint8) {
  188. this.reader.reset(uint8);
  189. return this.readAny();
  190. }
  191. decode(uint8) {
  192. this.reader.reset(uint8);
  193. return this.readAny();
  194. }
  195. readAny() {
  196. this.skipWhitespace();
  197. const reader = this.reader;
  198. const x = reader.x;
  199. const uint8 = reader.uint8;
  200. const char = uint8[x];
  201. switch (char) {
  202. case 34: {
  203. if (uint8[x + 1] === 0x64) {
  204. const bin = this.tryReadBin();
  205. if (bin)
  206. return bin;
  207. if (isUndefined(uint8, x + 2)) {
  208. reader.x = x + 35;
  209. return undefined;
  210. }
  211. }
  212. return this.readStr();
  213. }
  214. case 91:
  215. return this.readArr();
  216. case 102:
  217. return this.readFalse();
  218. case 110:
  219. return this.readNull();
  220. case 116:
  221. return this.readTrue();
  222. case 123:
  223. return this.readObj();
  224. default:
  225. if ((char >= 48 && char <= 57) || char === 45)
  226. return this.readNum();
  227. throw new Error('Invalid JSON');
  228. }
  229. }
  230. skipWhitespace() {
  231. const reader = this.reader;
  232. const uint8 = reader.uint8;
  233. let x = reader.x;
  234. let char = 0;
  235. while (true) {
  236. char = uint8[x];
  237. switch (char) {
  238. case 32:
  239. case 9:
  240. case 10:
  241. case 13:
  242. x++;
  243. continue;
  244. default:
  245. reader.x = x;
  246. return;
  247. }
  248. }
  249. }
  250. readNull() {
  251. if (this.reader.u32() !== 0x6e756c6c)
  252. throw new Error('Invalid JSON');
  253. return null;
  254. }
  255. readTrue() {
  256. if (this.reader.u32() !== 0x74727565)
  257. throw new Error('Invalid JSON');
  258. return true;
  259. }
  260. readFalse() {
  261. const reader = this.reader;
  262. if (reader.u8() !== 0x66 || reader.u32() !== 0x616c7365)
  263. throw new Error('Invalid JSON');
  264. return false;
  265. }
  266. readBool() {
  267. const reader = this.reader;
  268. switch (reader.uint8[reader.x]) {
  269. case 102:
  270. return this.readFalse();
  271. case 116:
  272. return this.readTrue();
  273. default:
  274. throw new Error('Invalid JSON');
  275. }
  276. }
  277. readNum() {
  278. const reader = this.reader;
  279. const uint8 = reader.uint8;
  280. let x = reader.x;
  281. let c = uint8[x++];
  282. const c1 = c;
  283. c = uint8[x++];
  284. if (!c || ((c < 45 || c > 57) && c !== 43 && c !== 69 && c !== 101)) {
  285. reader.x = x - 1;
  286. const num = +fromCharCode(c1);
  287. if (num !== num)
  288. throw new Error('Invalid JSON');
  289. return num;
  290. }
  291. const c2 = c;
  292. c = uint8[x++];
  293. if (!c || ((c < 45 || c > 57) && c !== 43 && c !== 69 && c !== 101)) {
  294. reader.x = x - 1;
  295. const num = +fromCharCode(c1, c2);
  296. if (num !== num)
  297. throw new Error('Invalid JSON');
  298. return num;
  299. }
  300. const c3 = c;
  301. c = uint8[x++];
  302. if (!c || ((c < 45 || c > 57) && c !== 43 && c !== 69 && c !== 101)) {
  303. reader.x = x - 1;
  304. const num = +fromCharCode(c1, c2, c3);
  305. if (num !== num)
  306. throw new Error('Invalid JSON');
  307. return num;
  308. }
  309. const c4 = c;
  310. c = uint8[x++];
  311. if (!c || ((c < 45 || c > 57) && c !== 43 && c !== 69 && c !== 101)) {
  312. reader.x = x - 1;
  313. const num = +fromCharCode(c1, c2, c3, c4);
  314. if (num !== num)
  315. throw new Error('Invalid JSON');
  316. return num;
  317. }
  318. const c5 = c;
  319. c = uint8[x++];
  320. if (!c || ((c < 45 || c > 57) && c !== 43 && c !== 69 && c !== 101)) {
  321. reader.x = x - 1;
  322. const num = +fromCharCode(c1, c2, c3, c4, c5);
  323. if (num !== num)
  324. throw new Error('Invalid JSON');
  325. return num;
  326. }
  327. const c6 = c;
  328. c = uint8[x++];
  329. if (!c || ((c < 45 || c > 57) && c !== 43 && c !== 69 && c !== 101)) {
  330. reader.x = x - 1;
  331. const num = +fromCharCode(c1, c2, c3, c4, c5, c6);
  332. if (num !== num)
  333. throw new Error('Invalid JSON');
  334. return num;
  335. }
  336. const c7 = c;
  337. c = uint8[x++];
  338. if (!c || ((c < 45 || c > 57) && c !== 43 && c !== 69 && c !== 101)) {
  339. reader.x = x - 1;
  340. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7);
  341. if (num !== num)
  342. throw new Error('Invalid JSON');
  343. return num;
  344. }
  345. const c8 = c;
  346. c = uint8[x++];
  347. if (!c || ((c < 45 || c > 57) && c !== 43 && c !== 69 && c !== 101)) {
  348. reader.x = x - 1;
  349. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8);
  350. if (num !== num)
  351. throw new Error('Invalid JSON');
  352. return num;
  353. }
  354. const c9 = c;
  355. c = uint8[x++];
  356. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  357. reader.x = x - 1;
  358. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9);
  359. if (num !== num)
  360. throw new Error('Invalid JSON');
  361. return num;
  362. }
  363. const c10 = c;
  364. c = uint8[x++];
  365. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  366. reader.x = x - 1;
  367. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10);
  368. if (num !== num)
  369. throw new Error('Invalid JSON');
  370. return num;
  371. }
  372. const c11 = c;
  373. c = uint8[x++];
  374. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  375. reader.x = x - 1;
  376. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11);
  377. if (num !== num)
  378. throw new Error('Invalid JSON');
  379. return num;
  380. }
  381. const c12 = c;
  382. c = uint8[x++];
  383. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  384. reader.x = x - 1;
  385. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
  386. if (num !== num)
  387. throw new Error('Invalid JSON');
  388. return num;
  389. }
  390. const c13 = c;
  391. c = uint8[x++];
  392. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  393. reader.x = x - 1;
  394. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
  395. if (num !== num)
  396. throw new Error('Invalid JSON');
  397. return num;
  398. }
  399. const c14 = c;
  400. c = uint8[x++];
  401. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  402. reader.x = x - 1;
  403. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14);
  404. if (num !== num)
  405. throw new Error('Invalid JSON');
  406. return num;
  407. }
  408. const c15 = c;
  409. c = uint8[x++];
  410. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  411. reader.x = x - 1;
  412. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15);
  413. if (num !== num)
  414. throw new Error('Invalid JSON');
  415. return num;
  416. }
  417. const c16 = c;
  418. c = uint8[x++];
  419. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  420. reader.x = x - 1;
  421. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16);
  422. if (num !== num)
  423. throw new Error('Invalid JSON');
  424. return num;
  425. }
  426. const c17 = c;
  427. c = uint8[x++];
  428. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  429. reader.x = x - 1;
  430. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17);
  431. if (num !== num)
  432. throw new Error('Invalid JSON');
  433. return num;
  434. }
  435. const c18 = c;
  436. c = uint8[x++];
  437. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  438. reader.x = x - 1;
  439. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18);
  440. if (num !== num)
  441. throw new Error('Invalid JSON');
  442. return num;
  443. }
  444. const c19 = c;
  445. c = uint8[x++];
  446. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  447. reader.x = x - 1;
  448. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19);
  449. if (num !== num)
  450. throw new Error('Invalid JSON');
  451. return num;
  452. }
  453. const c20 = c;
  454. c = uint8[x++];
  455. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  456. reader.x = x - 1;
  457. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20);
  458. if (num !== num)
  459. throw new Error('Invalid JSON');
  460. return num;
  461. }
  462. const c21 = c;
  463. c = uint8[x++];
  464. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  465. reader.x = x - 1;
  466. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21);
  467. if (num !== num)
  468. throw new Error('Invalid JSON');
  469. return num;
  470. }
  471. const c22 = c;
  472. c = uint8[x++];
  473. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  474. reader.x = x - 1;
  475. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22);
  476. if (num !== num)
  477. throw new Error('Invalid JSON');
  478. return num;
  479. }
  480. const c23 = c;
  481. c = uint8[x++];
  482. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  483. reader.x = x - 1;
  484. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23);
  485. if (num !== num)
  486. throw new Error('Invalid JSON');
  487. return num;
  488. }
  489. const c24 = c;
  490. c = uint8[x++];
  491. if (!c || ((c < 45 || c > 57) && c !== 69 && c !== 101)) {
  492. reader.x = x - 1;
  493. const num = +fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c24);
  494. if (num !== num)
  495. throw new Error('Invalid JSON');
  496. return num;
  497. }
  498. throw new Error('Invalid JSON');
  499. }
  500. readStr() {
  501. const reader = this.reader;
  502. const uint8 = reader.uint8;
  503. const char = uint8[reader.x++];
  504. if (char !== 0x22)
  505. throw new Error('Invalid JSON');
  506. const x0 = reader.x;
  507. const x1 = (0, util_1.findEndingQuote)(uint8, x0);
  508. let str = (0, decodeUtf8_1.decodeUtf8)(uint8, x0, x1 - x0);
  509. str = str.replace(REGEX_REPLACE_ESCAPED_CHARS, escapedCharReplacer);
  510. reader.x = x1 + 1;
  511. return str;
  512. }
  513. tryReadBin() {
  514. const reader = this.reader;
  515. const u8 = reader.uint8;
  516. let x = reader.x;
  517. if (u8[x++] !== 0x22)
  518. return undefined;
  519. const hasDataUrlPrefix = hasBinaryPrefix(u8, x);
  520. if (!hasDataUrlPrefix)
  521. return undefined;
  522. x += 37;
  523. const x0 = x;
  524. x = (0, util_1.findEndingQuote)(u8, x);
  525. reader.x = x0;
  526. const bin = (0, fromBase64Bin_1.fromBase64Bin)(reader.view, x0, x - x0);
  527. reader.x = x + 1;
  528. return bin;
  529. }
  530. readBin() {
  531. const reader = this.reader;
  532. const u8 = reader.uint8;
  533. let x = reader.x;
  534. if (u8[x++] !== 0x22)
  535. throw new Error('Invalid JSON');
  536. const hasDataUrlPrefix = hasBinaryPrefix(u8, x);
  537. if (!hasDataUrlPrefix)
  538. throw new Error('Invalid JSON');
  539. x += 37;
  540. const x0 = x;
  541. x = (0, util_1.findEndingQuote)(u8, x);
  542. reader.x = x0;
  543. const bin = (0, fromBase64Bin_1.fromBase64Bin)(reader.view, x0, x - x0);
  544. reader.x = x + 1;
  545. return bin;
  546. }
  547. readArr() {
  548. const reader = this.reader;
  549. if (reader.u8() !== 0x5b)
  550. throw new Error('Invalid JSON');
  551. const arr = [];
  552. const uint8 = reader.uint8;
  553. let first = true;
  554. while (true) {
  555. this.skipWhitespace();
  556. const char = uint8[reader.x];
  557. if (char === 0x5d)
  558. return reader.x++, arr;
  559. if (char === 0x2c)
  560. reader.x++;
  561. else if (!first)
  562. throw new Error('Invalid JSON');
  563. this.skipWhitespace();
  564. arr.push(this.readAny());
  565. first = false;
  566. }
  567. }
  568. readObj() {
  569. const reader = this.reader;
  570. if (reader.u8() !== 0x7b)
  571. throw new Error('Invalid JSON');
  572. const obj = {};
  573. const uint8 = reader.uint8;
  574. let first = true;
  575. while (true) {
  576. this.skipWhitespace();
  577. let char = uint8[reader.x];
  578. if (char === 0x7d)
  579. return reader.x++, obj;
  580. if (char === 0x2c)
  581. reader.x++;
  582. else if (!first)
  583. throw new Error('Invalid JSON');
  584. this.skipWhitespace();
  585. char = uint8[reader.x++];
  586. if (char !== 0x22)
  587. throw new Error('Invalid JSON');
  588. const key = (0, exports.readKey)(reader);
  589. if (key === '__proto__')
  590. throw new Error('Invalid JSON');
  591. this.skipWhitespace();
  592. if (reader.u8() !== 0x3a)
  593. throw new Error('Invalid JSON');
  594. this.skipWhitespace();
  595. obj[key] = this.readAny();
  596. first = false;
  597. }
  598. }
  599. }
  600. exports.JsonDecoder = JsonDecoder;
  601. //# sourceMappingURL=JsonDecoder.js.map