Skip to content

Commit e1d0038

Browse files
mrochfacebook-github-bot
authored andcommitted
> and } in JSX child text is a parse error
Summary: `}` and `>` are not valid text in a JSX child. you have to escape them using a JSXChildExpression containing a string, like `foo {'}'} bar`. ``` JSXChild : JSXText JSXElement { JSXChildExpressionopt } JSXText : JSXTextCharacter JSXTextopt JSXTextCharacter : SourceCharacter but not one of {, <, > or } ``` Reviewed By: gabelevi Differential Revision: D19172440 fbshipit-source-id: 5d2c03683ba705c87958c350d5ec98d9b0646705
1 parent 6433948 commit e1d0038

File tree

10 files changed

+233
-3
lines changed

10 files changed

+233
-3
lines changed

‎src/parser/flow_lexer.ml‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,9 @@ let rec jsx_text env mode buf raw lexbuf =
10251025
| "'"
10261026
| '"'
10271027
| '<'
1028-
| '{' ->
1028+
| '>'
1029+
| '{'
1030+
| '}' ->
10291031
let c = lexeme lexbuf in
10301032
begin
10311033
match (mode, c) with
@@ -1037,6 +1039,10 @@ let rec jsx_text env mode buf raw lexbuf =
10371039
* yet...they're not part of the JSX text *)
10381040
Sedlexing.rollback lexbuf;
10391041
env
1042+
| (JSX_CHILD_TEXT, ">") ->
1043+
unexpected_error_w_suggest env (loc_of_lexbuf env lexbuf) ">" "{'>'}"
1044+
| (JSX_CHILD_TEXT, "}") ->
1045+
unexpected_error_w_suggest env (loc_of_lexbuf env lexbuf) "}" "{'}'}"
10401046
| _ ->
10411047
Buffer.add_string raw c;
10421048
Buffer.add_string buf c;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(<foo bar=">" />)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"type":"Program",
3+
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":17}},
4+
"range":[0,17],
5+
"body":[
6+
{
7+
"type":"ExpressionStatement",
8+
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":17}},
9+
"range":[0,17],
10+
"expression":{
11+
"type":"JSXElement",
12+
"loc":{"source":null,"start":{"line":1,"column":1},"end":{"line":1,"column":16}},
13+
"range":[1,16],
14+
"openingElement":{
15+
"type":"JSXOpeningElement",
16+
"loc":{"source":null,"start":{"line":1,"column":1},"end":{"line":1,"column":16}},
17+
"range":[1,16],
18+
"name":{
19+
"type":"JSXIdentifier",
20+
"loc":{"source":null,"start":{"line":1,"column":2},"end":{"line":1,"column":5}},
21+
"range":[2,5],
22+
"name":"foo"
23+
},
24+
"attributes":[
25+
{
26+
"type":"JSXAttribute",
27+
"loc":{"source":null,"start":{"line":1,"column":6},"end":{"line":1,"column":13}},
28+
"range":[6,13],
29+
"name":{
30+
"type":"JSXIdentifier",
31+
"loc":{"source":null,"start":{"line":1,"column":6},"end":{"line":1,"column":9}},
32+
"range":[6,9],
33+
"name":"bar"
34+
},
35+
"value":{
36+
"type":"Literal",
37+
"loc":{"source":null,"start":{"line":1,"column":10},"end":{"line":1,"column":13}},
38+
"range":[10,13],
39+
"value":">",
40+
"raw":"\">\""
41+
}
42+
}
43+
],
44+
"selfClosing":true
45+
},
46+
"closingElement":null,
47+
"children":[]
48+
},
49+
"directive":null
50+
}
51+
],
52+
"comments":[]
53+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(<foo>></foo>)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"errors":[
3+
{
4+
"loc":{"source":null,"start":{"line":1,"column":6},"end":{"line":1,"column":7}},
5+
"message":"Unexpected token `>`. Did you mean `{'>'}`?"
6+
}
7+
],
8+
"type":"Program",
9+
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":14}},
10+
"range":[0,14],
11+
"body":[
12+
{
13+
"type":"ExpressionStatement",
14+
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":14}},
15+
"range":[0,14],
16+
"expression":{
17+
"type":"JSXElement",
18+
"loc":{"source":null,"start":{"line":1,"column":1},"end":{"line":1,"column":13}},
19+
"range":[1,13],
20+
"openingElement":{
21+
"type":"JSXOpeningElement",
22+
"loc":{"source":null,"start":{"line":1,"column":1},"end":{"line":1,"column":6}},
23+
"range":[1,6],
24+
"name":{
25+
"type":"JSXIdentifier",
26+
"loc":{"source":null,"start":{"line":1,"column":2},"end":{"line":1,"column":5}},
27+
"range":[2,5],
28+
"name":"foo"
29+
},
30+
"attributes":[],
31+
"selfClosing":false
32+
},
33+
"closingElement":{
34+
"type":"JSXClosingElement",
35+
"loc":{"source":null,"start":{"line":1,"column":7},"end":{"line":1,"column":13}},
36+
"range":[7,13],
37+
"name":{
38+
"type":"JSXIdentifier",
39+
"loc":{"source":null,"start":{"line":1,"column":9},"end":{"line":1,"column":12}},
40+
"range":[9,12],
41+
"name":"foo"
42+
}
43+
},
44+
"children":[
45+
{
46+
"type":"JSXText",
47+
"loc":{"source":null,"start":{"line":1,"column":6},"end":{"line":1,"column":7}},
48+
"range":[6,7],
49+
"value":"",
50+
"raw":""
51+
}
52+
]
53+
},
54+
"directive":null
55+
}
56+
],
57+
"comments":[]
58+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(<foo>}</foo>)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"errors":[
3+
{
4+
"loc":{"source":null,"start":{"line":1,"column":6},"end":{"line":1,"column":7}},
5+
"message":"Unexpected token `}`. Did you mean `{'}'}`?"
6+
}
7+
],
8+
"type":"Program",
9+
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":14}},
10+
"range":[0,14],
11+
"body":[
12+
{
13+
"type":"ExpressionStatement",
14+
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":14}},
15+
"range":[0,14],
16+
"expression":{
17+
"type":"JSXElement",
18+
"loc":{"source":null,"start":{"line":1,"column":1},"end":{"line":1,"column":13}},
19+
"range":[1,13],
20+
"openingElement":{
21+
"type":"JSXOpeningElement",
22+
"loc":{"source":null,"start":{"line":1,"column":1},"end":{"line":1,"column":6}},
23+
"range":[1,6],
24+
"name":{
25+
"type":"JSXIdentifier",
26+
"loc":{"source":null,"start":{"line":1,"column":2},"end":{"line":1,"column":5}},
27+
"range":[2,5],
28+
"name":"foo"
29+
},
30+
"attributes":[],
31+
"selfClosing":false
32+
},
33+
"closingElement":{
34+
"type":"JSXClosingElement",
35+
"loc":{"source":null,"start":{"line":1,"column":7},"end":{"line":1,"column":13}},
36+
"range":[7,13],
37+
"name":{
38+
"type":"JSXIdentifier",
39+
"loc":{"source":null,"start":{"line":1,"column":9},"end":{"line":1,"column":12}},
40+
"range":[9,12],
41+
"name":"foo"
42+
}
43+
},
44+
"children":[
45+
{
46+
"type":"JSXText",
47+
"loc":{"source":null,"start":{"line":1,"column":6},"end":{"line":1,"column":7}},
48+
"range":[6,7],
49+
"value":"",
50+
"raw":""
51+
}
52+
]
53+
},
54+
"directive":null
55+
}
56+
],
57+
"comments":[]
58+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(<foo bar="}" />)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"type":"Program",
3+
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":17}},
4+
"range":[0,17],
5+
"body":[
6+
{
7+
"type":"ExpressionStatement",
8+
"loc":{"source":null,"start":{"line":1,"column":0},"end":{"line":1,"column":17}},
9+
"range":[0,17],
10+
"expression":{
11+
"type":"JSXElement",
12+
"loc":{"source":null,"start":{"line":1,"column":1},"end":{"line":1,"column":16}},
13+
"range":[1,16],
14+
"openingElement":{
15+
"type":"JSXOpeningElement",
16+
"loc":{"source":null,"start":{"line":1,"column":1},"end":{"line":1,"column":16}},
17+
"range":[1,16],
18+
"name":{
19+
"type":"JSXIdentifier",
20+
"loc":{"source":null,"start":{"line":1,"column":2},"end":{"line":1,"column":5}},
21+
"range":[2,5],
22+
"name":"foo"
23+
},
24+
"attributes":[
25+
{
26+
"type":"JSXAttribute",
27+
"loc":{"source":null,"start":{"line":1,"column":6},"end":{"line":1,"column":13}},
28+
"range":[6,13],
29+
"name":{
30+
"type":"JSXIdentifier",
31+
"loc":{"source":null,"start":{"line":1,"column":6},"end":{"line":1,"column":9}},
32+
"range":[6,9],
33+
"name":"bar"
34+
},
35+
"value":{
36+
"type":"Literal",
37+
"loc":{"source":null,"start":{"line":1,"column":10},"end":{"line":1,"column":13}},
38+
"range":[10,13],
39+
"value":"}",
40+
"raw":"\"}\""
41+
}
42+
}
43+
],
44+
"selfClosing":true
45+
},
46+
"closingElement":null,
47+
"children":[]
48+
},
49+
"directive":null
50+
}
51+
],
52+
"comments":[]
53+
}

‎tests/react_jsx_fragments/test.js‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ React.createElement(React.Fragment, null);
66

77
< ></>; // success
88

9-
<>></>; // success
10-
119
<></>; // success
1210

1311
<>hi</>; // success

0 commit comments

Comments
 (0)