Make JSON parser stricter (#10346)

This commit is contained in:
fisker Cheung authored and GitHub committed 2021-02-23 13:33:10 +02:00
1 parent eea7d11883
commit d544585d87
6 files changed
+109 -12

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
#### Stricter JSON parser (#10346 by @fisker)
Previously we allow all kinds of JavaScript expressions in `json` and `json5` parser, now they are stricter.
<!-- prettier-ignore -->
```js
// Input
[1, 2, 1 + 2]
// Prettier stable
[1, 2, 1 + 2]
// Prettier main
SyntaxError: BinaryExpression is not allowed in JSON. (1:8)
> 1 | [1, 2, 1 + 2]
| ^
```
+29 -12
View File
@@ -153,6 +153,7 @@ const parseTypeScript = createParse(
["typescript"]
);
const parseExpression = createParse("parseExpression", ["jsx"]);
const parseJson = createJsonParse();
const messagesShouldThrow = new Set([
// TSErrors.UnexpectedTypeAnnotation
@@ -179,15 +180,31 @@ function shouldRethrowRecoveredError(error) {
return messagesShouldThrow.has(message);
}
function parseJson(text, parsers, opts) {
const ast = parseExpression(text, parsers, opts);
function createJsonParse(options = {}) {
const { allowComments = true } = options;
for (const comment of ast.comments) {
assertJsonNode(comment);
}
assertJsonNode(ast);
return function parse(text /*, parsers, options*/) {
let ast;
try {
ast = require("@babel/parser").parseExpression(text, {
tokens: true,
ranges: true,
});
} catch (error) {
throw createParseError(error);
}
return ast;
if (!allowComments) {
// @ts-ignore
for (const comment of ast.comments) {
assertJsonNode(comment);
}
}
assertJsonNode(ast);
return ast;
};
}
function assertJsonNode(node, parent) {
@@ -262,15 +279,15 @@ module.exports = {
babel,
"babel-flow": createParser(parseFlow),
"babel-ts": createParser(parseTypeScript),
json: {
...babelExpression,
json: createParser({
parse: parseJson,
hasPragma() {
return true;
},
},
json5: babelExpression,
}),
json5: createParser(parseJson),
"json-stringify": createParser({
parse: parseJson,
parse: createJsonParse({ allowComments: false }),
astFormat: "estree-json",
}),
/** @internal */
@@ -1,5 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`invalid-json.md - {"trailingComma":"all"} format 1`] = `
====================================options=====================================
parsers: ["markdown"]
printWidth: 80
trailingComma: "all"
| printWidth
=====================================input======================================
<!-- #10333 -->
\`\`\`json
packages\\the-hub\\cypress\\fixtures\\gridConfiguration.json
\`\`\`
=====================================output=====================================
<!-- #10333 -->
\`\`\`json
packages\\the-hub\\cypress\\fixtures\\gridConfiguration.json
\`\`\`
================================================================================
`;
exports[`jsonc.md - {"trailingComma":"all"} format 1`] = `
====================================options=====================================
parsers: ["markdown"]
@@ -0,0 +1,4 @@
<!-- #10333 -->
```json
packages\the-hub\cypress\fixtures\gridConfiguration.json
```
@@ -1,11 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`snippet: #0 [json] format 1`] = `
"Expecting Unicode escape sequence \\\\uXXXX (1:10)
> 1 | packages\\\\the-hub\\\\cypress\\\\fixtures\\\\gridConfiguration.json
| ^"
`;
exports[`snippet: #0 [json-stringify] format 1`] = `
"ObjectProperty with shorthand=true is not allowed in JSON. (1:2)
> 1 | {foo}
| ^"
`;
exports[`snippet: #1 [json] format 1`] = `
"BinaryExpression is not allowed in JSON. (1:1)
> 1 | 1+2
| ^"
`;
exports[`snippet: #1 [json-stringify] format 1`] = `
"ObjectProperty with computed=true is not allowed in JSON. (1:2)
> 1 | {[\\"foo\\"]:\\"bar\\"}
@@ -35,3 +47,16 @@ exports[`snippet: #5 [json-stringify] format 1`] = `
> 1 | {\\"foo\\": () => {}}
| ^"
`;
exports[`snippet: #6 [json-stringify] format 1`] = `
"CommentBlock is not allowed in JSON. (1:1)
> 1 | /* comment */{\\"foo\\": 1}
| ^"
`;
exports[`snippet: #7 [json-stringify] format 1`] = `
"CommentLine is not allowed in JSON. (1:1)
> 1 | // comment
| ^
2 | {\\"foo\\": 1}"
`;
+13
View File
@@ -8,7 +8,20 @@ run_spec(
'{"foo": false || "bar"}',
'{"foo": undefined}',
'{"foo": () => {}}',
'/* comment */{"foo": 1}',
'// comment\n{"foo": 1}',
],
},
["json-stringify"]
);
run_spec(
{
dirname: __dirname,
snippets: [
"packages\\the-hub\\cypress\\fixtures\\gridConfiguration.json",
"1+2",
],
},
["json"]
);