Skip to content

Commit 5f1cf01

Browse files
authoredFeb 14, 2024
fix(es/react): Validate pragma before parsing (#8637)
**Related issue:** - Closes #7938
1 parent 09bedec commit 5f1cf01

File tree

5 files changed

+90
-22
lines changed

5 files changed

+90
-22
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"jsc": {
3+
"parser": {
4+
"syntax": "typescript",
5+
"tsx": true
6+
},
7+
"target": "es2019",
8+
"loose": false,
9+
"minify": {
10+
"compress": false,
11+
"mangle": false
12+
}
13+
},
14+
"module": {
15+
"type": "es6"
16+
},
17+
"minify": false,
18+
"isModule": true
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/** @jsx foo-bar */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"jsc": {
3+
"parser": {
4+
"syntax": "typescript",
5+
"tsx": true
6+
},
7+
"target": "es2022",
8+
"loose": false,
9+
"minify": {
10+
"compress": false,
11+
"mangle": false
12+
},
13+
"transform": {
14+
"react": {
15+
"importSource": "npm:react",
16+
"runtime": "automatic"
17+
}
18+
}
19+
},
20+
"module": {
21+
"type": "es6"
22+
},
23+
"minify": false,
24+
"isModule": true
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/** @jsx a- */

‎crates/swc_ecma_transforms_react/src/jsx/mod.rs

+44-22
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ pub fn parse_expr_for_jsx(
118118
src: String,
119119
top_level_mark: Mark,
120120
) -> Arc<Box<Expr>> {
121-
let fm = cm.new_source_file(FileName::Internal(format!("<jsx-config-{}.js>", name)), src);
121+
let fm = cm.new_source_file(FileName::Internal(format!("jsx-config-{}.js", name)), src);
122122

123123
parse_file_as_expr(
124124
&fm,
@@ -131,7 +131,7 @@ pub fn parse_expr_for_jsx(
131131
if HANDLER.is_set() {
132132
HANDLER.with(|h| {
133133
e.into_diagnostic(h)
134-
.note("error detected while parsing option for classic jsx transform")
134+
.note("Failed to parse jsx pragma")
135135
.emit()
136136
})
137137
}
@@ -339,30 +339,34 @@ impl JsxDirectives {
339339
}
340340
Some("@jsxFrag") => {
341341
if let Some(src) = val {
342-
// TODO: Optimize
343-
let mut e = (*parse_expr_for_jsx(
344-
cm,
345-
"module-jsx-pragma-frag",
346-
src.to_string(),
347-
top_level_mark,
348-
))
349-
.clone();
350-
respan(&mut e, cmt.span);
351-
res.pragma_frag = Some(e.into())
342+
if is_valid_for_pragma(src) {
343+
// TODO: Optimize
344+
let mut e = (*parse_expr_for_jsx(
345+
cm,
346+
"module-jsx-pragma-frag",
347+
src.to_string(),
348+
top_level_mark,
349+
))
350+
.clone();
351+
respan(&mut e, cmt.span);
352+
res.pragma_frag = Some(e.into())
353+
}
352354
}
353355
}
354356
Some("@jsx") => {
355357
if let Some(src) = val {
356-
// TODO: Optimize
357-
let mut e = (*parse_expr_for_jsx(
358-
cm,
359-
"module-jsx-pragma",
360-
src.to_string(),
361-
top_level_mark,
362-
))
363-
.clone();
364-
respan(&mut e, cmt.span);
365-
res.pragma = Some(e.into());
358+
if is_valid_for_pragma(src) {
359+
// TODO: Optimize
360+
let mut e = (*parse_expr_for_jsx(
361+
cm,
362+
"module-jsx-pragma",
363+
src.to_string(),
364+
top_level_mark,
365+
))
366+
.clone();
367+
respan(&mut e, cmt.span);
368+
res.pragma = Some(e.into());
369+
}
366370
}
367371
}
368372
_ => {}
@@ -375,6 +379,24 @@ impl JsxDirectives {
375379
}
376380
}
377381

382+
fn is_valid_for_pragma(s: &str) -> bool {
383+
if s.is_empty() {
384+
return false;
385+
}
386+
387+
if !s.starts_with(|c: char| Ident::is_valid_start(c)) {
388+
return false;
389+
}
390+
391+
for c in s.chars() {
392+
if !Ident::is_valid_continue(c) && c != '.' {
393+
return false;
394+
}
395+
}
396+
397+
true
398+
}
399+
378400
impl<C> Jsx<C>
379401
where
380402
C: Comments,

0 commit comments

Comments
 (0)
Please sign in to comment.