Skip to content

Commit fbb3ebf

Browse files
authored
Merge pull request #155 from WalletConnect/fix/safeJsonParse
fix: safe json parse
2 parents 458c711 + 7c66561 commit fbb3ebf

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

misc/safe-json/src/index.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* JSONStringify & JSONParse used from json-with-bigint
2+
* JSONStringify & JSONParse inspired by json-with-bigint
33
* source: https://github.com/Ivan-Korolenko/json-with-bigint
44
*/
55
/*
@@ -20,12 +20,12 @@ const JSONParse = (json: string) => {
2020
/*
2121
Big numbers are found and marked using Regex with this condition:
2222
Number's length is bigger than 16 || Number's length is 16 and any numerical digit of the number is greater than that of the Number.MAX_SAFE_INTEGER
23+
Additionally, it skips values that are strings (between double quotes).
2324
*/
2425
// prettier-ignore
2526
// eslint-disable-next-line no-useless-escape
26-
const numbersBiggerThanMaxInt = /([\[:])?(\d{17,}|(?:[9](?:[1-9]07199254740991|0[1-9]7199254740991|00[8-9]199254740991|007[2-9]99254740991|007199[3-9]54740991|0071992[6-9]4740991|00719925[5-9]740991|007199254[8-9]40991|0071992547[5-9]0991|00719925474[1-9]991|00719925474099[2-9])))([,\}\]])/g;
27-
const serializedData = json.replace(numbersBiggerThanMaxInt, `$1"$2n"$3`);
28-
27+
const numbersBiggerThanMaxInt = /(?<!")(?<=:)\b(\d{17,}|(?:[9](?:[1-9]07199254740991|0[1-9]7199254740991|00[8-9]199254740991|007[2-9]99254740991|007199[3-9]54740991|0071992[6-9]4740991|00719925[5-9]740991|007199254[8-9]40991|0071992547[5-9]0991|00719925474[1-9]991|00719925474099[2-9])))(?=[,\}\]]|$)/g;
28+
const serializedData = json.replace(numbersBiggerThanMaxInt, (match) => `"${match}n"`);
2929
return JSON.parse(serializedData, (_, value) => {
3030
const isCustomFormatBigInt = typeof value === "string" && value.match(/^\d+n$/);
3131

@@ -41,7 +41,9 @@ export function safeJsonParse<T = any>(value: string): T | string {
4141
}
4242
try {
4343
return JSONParse(value);
44-
} catch {
44+
} catch (e) {
45+
// eslint-disable-next-line no-console
46+
console.error("safeJsonParse error:", e);
4547
return value;
4648
}
4749
}

misc/safe-json/test/index.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,27 @@ describe("@walletconnect/safe-json", () => {
2828
const result = safeJsonParse(safeJsonStringify({ bigint: BigInt(1) }));
2929
chai.expect(result).to.deep.eq({ bigint: BigInt(1) });
3030
});
31+
it("should handle number inside string literal. Case 1", () => {
32+
const nested = '{"x":"12345678901234567,"}';
33+
const result = safeJsonParse(nested);
34+
chai.expect(result).to.deep.eq(JSON.parse(nested));
35+
const big = safeJsonParse(safeJsonStringify({ bigint: BigInt(1) }));
36+
chai.expect(big).to.deep.eq({ bigint: BigInt(1) });
37+
});
38+
39+
it("should handle number inside string literal. Case 2", () => {
40+
const nested =
41+
'{"params":{"proposer":{"metadata":{"description":"Trade Any Token on DODOEX. Swap ETH to WETH at 0.99852536006139370845107244063040676283327993685155310925333096461126073315184832, 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"}}}}';
42+
const result = safeJsonParse(nested);
43+
chai.expect(result).to.deep.eq(JSON.parse(nested));
44+
});
45+
46+
it("should handle BigInt", () => {
47+
const bigIntId = "1702044452707006208";
48+
const data = `{"id":${bigIntId},"jsonrpc":"2.0","result":"cb0072aaf3f3aab9b5a334f3a273634a2a6d2bee5fe7be205dc9f30f032c9734"}`;
49+
const result = safeJsonParse(data);
50+
chai.expect(result.id).to.deep.eq(BigInt(bigIntId));
51+
});
3152
});
3253
describe("safeJsonStringify", () => {
3354
it("should return a stringfied json", () => {

0 commit comments

Comments
 (0)