Skip to content

Commit

Permalink
chore: lint with prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Jun 12, 2023
1 parent 4aa3592 commit 6aa42c6
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 23 deletions.
1 change: 1 addition & 0 deletions .prettierrc
@@ -0,0 +1 @@
{}
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -22,7 +22,8 @@
"bench": "pnpm build && node ./bench.cjs",
"build": "unbuild",
"dev": "vitest dev",
"lint": "eslint --ext .ts .",
"lint": "eslint --ext .ts . && prettier -c src test",
"lint:fix": "eslint --ext .ts . --fix && prettier -w src test",
"release": "pnpm test && pnpm build && standard-version && git push --follow-tags && pnpm publish",
"test": "pnpm lint && vitest run --coverage"
},
Expand All @@ -32,6 +33,7 @@
"benchmark": "^2.1.4",
"eslint": "^8.42.0",
"eslint-config-unjs": "^0.2.1",
"prettier": "^2.8.8",
"secure-json-parse": "^2.7.0",
"standard-version": "^9.5.0",
"typescript": "^5.1.3",
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 32 additions & 13 deletions src/index.ts
@@ -1,38 +1,57 @@
// https://github.com/fastify/secure-json-parse
// https://github.com/hapijs/bourne
const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
const suspectProtoRx =
/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
const suspectConstructorRx =
/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;

const JsonSigRx = /^\s*["[{]|^\s*-?\d[\d.]{0,14}\s*$/;

function jsonParseTransform (key: string, value: any): any {
function jsonParseTransform(key: string, value: any): any {
if (key === "__proto__") {
return;
}
if (key === "constructor" && value && typeof value === "object" && ("prototype" in value)) {
if (
key === "constructor" &&
value &&
typeof value === "object" &&
"prototype" in value
) {
// Has possible malicious prototype
return;
}
return value;
}

export type Options = {
strict?: boolean
}
strict?: boolean;
};

export default function destr (value: any, options: Options = {}): any {
export default function destr(value: any, options: Options = {}): any {
if (typeof value !== "string") {
return value;
}

const _lval = value.toLowerCase().trim();
if (_lval === "true") { return true; }
if (_lval === "false") { return false; }
if (_lval === "true") {
return true;
}
if (_lval === "false") {
return false;
}
// eslint-disable-next-line unicorn/no-null
if (_lval === "null") { return null; }
if (_lval === "nan") { return Number.NaN; }
if (_lval === "infinity") { return Number.POSITIVE_INFINITY; }
if (_lval === "undefined") { return undefined; }
if (_lval === "null") {
return null;

Check failure on line 44 in src/index.ts

View workflow job for this annotation

GitHub Actions / ci

Use `undefined` instead of `null`
}
if (_lval === "nan") {
return Number.NaN;
}
if (_lval === "infinity") {
return Number.POSITIVE_INFINITY;
}
if (_lval === "undefined") {
return undefined;
}

if (!JsonSigRx.test(value)) {
if (options.strict) {
Expand Down
20 changes: 11 additions & 9 deletions test/index.test.ts
Expand Up @@ -12,7 +12,7 @@ describe("destr", () => {
/* eslint-disable-next-line unicorn/no-null */
{ input: null },
{ input: Number.POSITIVE_INFINITY },
{ input: undefined }
{ input: undefined },
];

for (const testCase of testCases) {
Expand Down Expand Up @@ -55,18 +55,18 @@ describe("destr", () => {
it("parses with surrounding spaces", () => {
expect(destr(" true ")).toBe(true);
expect(destr(" -123 ")).toStrictEqual(-123);
expect(destr(" { \"test\": 123 } ")).toStrictEqual({ test: 123 });
expect(destr(' { "test": 123 } ')).toStrictEqual({ test: 123 });
});

it("parses valid JSON texts", () => {
const testCases = [
{ input: "{}", output: {} },
{ input: "[]", output: [] },
{ input: "{ \"key\": \"value\" }", output: { key: "value" } },
{ input: "{ \"constructor\": \"value\" }", output: { constructor: "value" } },
{ input: '{ "key": "value" }', output: { key: "value" } },
{ input: '{ "constructor": "value" }', output: { constructor: "value" } },
// eslint-disable-next-line unicorn/no-null
{ input: '{ "constructor": null }', output: { constructor: null } },
{ input: "[1,2,3]", output: [1, 2, 3] }
{ input: "[1,2,3]", output: [1, 2, 3] },
];

for (const testCase of testCases) {
Expand All @@ -78,7 +78,7 @@ describe("destr", () => {
const testCases = [
{ input: '{ "__proto__": {} }', output: {} },
{ input: '{ "constructor": { "prototype": {} } }', output: {} },
{ input: '{ "constructor": { "prototype": null } }', output: {} }
{ input: '{ "constructor": { "prototype": null } }', output: {} },
];

for (const testCase of testCases) {
Expand All @@ -92,7 +92,7 @@ describe("destr", () => {
{ input: "[ " },
{ input: '" ' },
{ input: "[1,2,3]?" },
{ input: "invalid JSON text" }
{ input: "invalid JSON text" },
];

for (const testCase of testCases) {
Expand All @@ -106,11 +106,13 @@ describe("destr", () => {
{ input: "[ ", output: "Unexpected end of JSON input" },
{ input: '" ', output: "Unexpected end of JSON input" },
{ input: "[1,2,3]?", output: "Unexpected token" },
{ input: "invalid JSON text", output: "Invalid JSON" }
{ input: "invalid JSON text", output: "Invalid JSON" },
];

for (const testCase of testCases) {
expect(() => destr(testCase.input, { strict: true })).toThrowError(testCase.output || "");
expect(() => destr(testCase.input, { strict: true })).toThrowError(
testCase.output || ""
);
}
});
});

0 comments on commit 6aa42c6

Please sign in to comment.