Make JSON parser stricter (#10346)
This commit is contained in:
1 parent
eea7d11883
commit
d544585d87
6 files changed
+109
-12
No files matched your search
@@ -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]
|
||||
| ^
|
||||
```
|
||||
@@ -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}"
|
||||
`;
|
||||
@@ -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"]
|
||||
);
|
||||
Reference in new issue
Block a user