aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-08-08 14:17:14 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-08-08 14:17:14 -0700
commit33832aa887d2fbbf121ec2522767a8cf1783a3f9 (patch)
tree55ac99090d4bdd15d9a1051740965c8e46bc95c6
parent063ac7dce5705a148ec5b268fe9c62e2e0f6371d (diff)
downloadbun-33832aa887d2fbbf121ec2522767a8cf1783a3f9.tar.gz
bun-33832aa887d2fbbf121ec2522767a8cf1783a3f9.tar.zst
bun-33832aa887d2fbbf121ec2522767a8cf1783a3f9.zip
Fix infinite loop when class statements are missing an identifier. This may expose a larger issue. We used to panic on lexer errors, but we don't anymore.
Former-commit-id: f4e14ece75b3d381798e317a45833ffa929e900f
-rw-r--r--src/js_parser/js_parser.zig21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 1d41945c1..112c61553 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -4620,17 +4620,24 @@ pub fn NewParser(
}
var is_identifier = p.lexer.token == .t_identifier;
- var is_strict_modereserved_word = is_identifier and js_lexer.StrictModeReservedWords.has(p.lexer.identifier);
- if (!opts.is_name_optional or (is_identifier and !is_strict_modereserved_word)) {
+ if (!opts.is_name_optional or (is_identifier and (!is_typescript_enabled or !strings.eqlComptime(p.lexer.identifier, "interface")))) {
var name_loc = p.lexer.loc();
var name_text = p.lexer.identifier;
- if (is_strict_modereserved_word) {
- try p.lexer.unexpected();
+ try p.lexer.expect(.t_identifier);
+
+ // We must return here
+ // or the lexer will crash loop!
+ // example:
+ // export class {}
+ if (!is_identifier) {
return error.SyntaxError;
}
- try p.lexer.expect(.t_identifier);
+ if (p.fn_or_arrow_data_parse.allow_await != .allow_ident and strings.eqlComptime(name_text, "await")) {
+ try p.log.addRangeError(p.source, p.lexer.range(), "Cannot use \"await\" as an identifier here");
+ }
+
name = LocRef{ .loc = name_loc, .ref = null };
if (!opts.is_typescript_declare) {
(name orelse unreachable).ref = p.declareSymbol(.class, name_loc, name_text) catch unreachable;
@@ -11981,7 +11988,9 @@ pub fn NewParser(
}
// We must relocate vars in order to safely handle removing if/else depending on NODE_ENV.
- if (data.kind == .k_var) {
+ // Edgecase:
+ // `export var` is skipped because it's unnecessary. That *should* be a noop, but it loses the `is_export` flag if we're in HMR.
+ if (data.kind == .k_var and !data.is_export) {
const relocated = p.maybeRelocateVarsToTopLevel(data.decls, .normal);
if (relocated.ok) {
if (relocated.stmt) |new_stmt| {