fix(es/react): Validate pragma before parsing (#8637)

**Related issue:**

 - Closes #7938
This commit is contained in:
Donny/강동윤 2024-02-14 11:39:40 +09:00 committed by GitHub
parent 09bedecff6
commit 5f1cf01823
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 90 additions and 22 deletions

View File

@ -0,0 +1,19 @@
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"target": "es2019",
"loose": false,
"minify": {
"compress": false,
"mangle": false
}
},
"module": {
"type": "es6"
},
"minify": false,
"isModule": true
}

View File

@ -0,0 +1 @@
/** @jsx foo-bar */

View File

@ -0,0 +1,25 @@
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"target": "es2022",
"loose": false,
"minify": {
"compress": false,
"mangle": false
},
"transform": {
"react": {
"importSource": "npm:react",
"runtime": "automatic"
}
}
},
"module": {
"type": "es6"
},
"minify": false,
"isModule": true
}

View File

@ -0,0 +1 @@
/** @jsx a- */

View File

@ -118,7 +118,7 @@ pub fn parse_expr_for_jsx(
src: String,
top_level_mark: Mark,
) -> Arc<Box<Expr>> {
let fm = cm.new_source_file(FileName::Internal(format!("<jsx-config-{}.js>", name)), src);
let fm = cm.new_source_file(FileName::Internal(format!("jsx-config-{}.js", name)), src);
parse_file_as_expr(
&fm,
@ -131,7 +131,7 @@ pub fn parse_expr_for_jsx(
if HANDLER.is_set() {
HANDLER.with(|h| {
e.into_diagnostic(h)
.note("error detected while parsing option for classic jsx transform")
.note("Failed to parse jsx pragma")
.emit()
})
}
@ -339,30 +339,34 @@ impl JsxDirectives {
}
Some("@jsxFrag") => {
if let Some(src) = val {
// TODO: Optimize
let mut e = (*parse_expr_for_jsx(
cm,
"module-jsx-pragma-frag",
src.to_string(),
top_level_mark,
))
.clone();
respan(&mut e, cmt.span);
res.pragma_frag = Some(e.into())
if is_valid_for_pragma(src) {
// TODO: Optimize
let mut e = (*parse_expr_for_jsx(
cm,
"module-jsx-pragma-frag",
src.to_string(),
top_level_mark,
))
.clone();
respan(&mut e, cmt.span);
res.pragma_frag = Some(e.into())
}
}
}
Some("@jsx") => {
if let Some(src) = val {
// TODO: Optimize
let mut e = (*parse_expr_for_jsx(
cm,
"module-jsx-pragma",
src.to_string(),
top_level_mark,
))
.clone();
respan(&mut e, cmt.span);
res.pragma = Some(e.into());
if is_valid_for_pragma(src) {
// TODO: Optimize
let mut e = (*parse_expr_for_jsx(
cm,
"module-jsx-pragma",
src.to_string(),
top_level_mark,
))
.clone();
respan(&mut e, cmt.span);
res.pragma = Some(e.into());
}
}
}
_ => {}
@ -375,6 +379,24 @@ impl JsxDirectives {
}
}
fn is_valid_for_pragma(s: &str) -> bool {
if s.is_empty() {
return false;
}
if !s.starts_with(|c: char| Ident::is_valid_start(c)) {
return false;
}
for c in s.chars() {
if !Ident::is_valid_continue(c) && c != '.' {
return false;
}
}
true
}
impl<C> Jsx<C>
where
C: Comments,