Skip to content

Commit

Permalink
Merge pull request #155 from WalletConnect/fix/safeJsonParse
Browse files Browse the repository at this point in the history
fix: safe json parse
  • Loading branch information
ganchoradkov authored Dec 22, 2023
2 parents 458c711 + 7c66561 commit fbb3ebf
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
12 changes: 7 additions & 5 deletions misc/safe-json/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* JSONStringify & JSONParse used from json-with-bigint
* JSONStringify & JSONParse inspired by json-with-bigint
* source: https://github.com/Ivan-Korolenko/json-with-bigint
*/
/*
Expand All @@ -20,12 +20,12 @@ const JSONParse = (json: string) => {
/*
Big numbers are found and marked using Regex with this condition:
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
Additionally, it skips values that are strings (between double quotes).
*/
// prettier-ignore
// eslint-disable-next-line no-useless-escape
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;
const serializedData = json.replace(numbersBiggerThanMaxInt, `$1"$2n"$3`);

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;
const serializedData = json.replace(numbersBiggerThanMaxInt, (match) => `"${match}n"`);
return JSON.parse(serializedData, (_, value) => {
const isCustomFormatBigInt = typeof value === "string" && value.match(/^\d+n$/);

Expand All @@ -41,7 +41,9 @@ export function safeJsonParse<T = any>(value: string): T | string {
}
try {
return JSONParse(value);
} catch {
} catch (e) {
// eslint-disable-next-line no-console
console.error("safeJsonParse error:", e);
return value;
}
}
Expand Down
21 changes: 21 additions & 0 deletions misc/safe-json/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,27 @@ describe("@walletconnect/safe-json", () => {
const result = safeJsonParse(safeJsonStringify({ bigint: BigInt(1) }));
chai.expect(result).to.deep.eq({ bigint: BigInt(1) });
});
it("should handle number inside string literal. Case 1", () => {
const nested = '{"x":"12345678901234567,"}';
const result = safeJsonParse(nested);
chai.expect(result).to.deep.eq(JSON.parse(nested));
const big = safeJsonParse(safeJsonStringify({ bigint: BigInt(1) }));
chai.expect(big).to.deep.eq({ bigint: BigInt(1) });
});

it("should handle number inside string literal. Case 2", () => {
const nested =
'{"params":{"proposer":{"metadata":{"description":"Trade Any Token on DODOEX. Swap ETH to WETH at 0.99852536006139370845107244063040676283327993685155310925333096461126073315184832, 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"}}}}';
const result = safeJsonParse(nested);
chai.expect(result).to.deep.eq(JSON.parse(nested));
});

it("should handle BigInt", () => {
const bigIntId = "1702044452707006208";
const data = `{"id":${bigIntId},"jsonrpc":"2.0","result":"cb0072aaf3f3aab9b5a334f3a273634a2a6d2bee5fe7be205dc9f30f032c9734"}`;
const result = safeJsonParse(data);
chai.expect(result.id).to.deep.eq(BigInt(bigIntId));
});
});
describe("safeJsonStringify", () => {
it("should return a stringfied json", () => {
Expand Down

0 comments on commit fbb3ebf

Please sign in to comment.