Skip to content

Commit

Permalink
LibJS: Disallow yield expression correctly in formal parameters
Browse files Browse the repository at this point in the history
And add ZERO WIDTH NO BREAK SPACE to valid whitespace.
  • Loading branch information
davidot authored and linusg committed Aug 24, 2021
1 parent 7bcffd1 commit c108c8f
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Userland/Libraries/LibJS/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ bool Lexer::is_whitespace() const
if (!is_unicode_character())
return false;
auto code_point = current_code_point();
if (code_point == NO_BREAK_SPACE)
if (code_point == NO_BREAK_SPACE || code_point == ZERO_WIDTH_NO_BREAK_SPACE)
return true;

static auto space_separator_category = Unicode::general_category_from_string("Space_Separator"sv);
Expand Down
8 changes: 6 additions & 2 deletions Userland/Libraries/LibJS/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,7 @@ NonnullRefPtr<AssignmentExpression> Parser::parse_assignment_expression(Assignme
parser.m_state.allow_super_property_lookup = m_state.allow_super_property_lookup;
parser.m_state.allow_super_constructor_call = m_state.allow_super_constructor_call;
parser.m_state.in_function_context = m_state.in_function_context;
parser.m_state.in_formal_parameter_context = m_state.in_formal_parameter_context;
parser.m_state.in_generator_function_context = m_state.in_generator_function_context;
parser.m_state.in_arrow_function_context = m_state.in_arrow_function_context;
parser.m_state.in_break_context = m_state.in_break_context;
Expand Down Expand Up @@ -1631,6 +1632,10 @@ NonnullRefPtr<NewExpression> Parser::parse_new_expression()
NonnullRefPtr<YieldExpression> Parser::parse_yield_expression()
{
auto rule_start = push_start();

if (m_state.in_formal_parameter_context)
syntax_error("'Yield' expression is not allowed in formal parameters of generator function");

consume(TokenType::Yield);
RefPtr<Expression> argument;
bool yield_from = false;
Expand Down Expand Up @@ -1841,6 +1846,7 @@ Vector<FunctionNode::Parameter> Parser::parse_formal_parameters(int& function_le
auto rule_start = push_start();
bool has_default_parameter = false;
bool has_rest_parameter = false;
TemporaryChange formal_parameter_context_change { m_state.in_formal_parameter_context, true };

Vector<FunctionNode::Parameter> parameters;

Expand Down Expand Up @@ -1914,8 +1920,6 @@ Vector<FunctionNode::Parameter> Parser::parse_formal_parameters(int& function_le
bool is_generator = parse_options & FunctionNodeParseOptions::IsGeneratorFunction;
if ((is_generator || m_state.strict_mode) && default_value && default_value->fast_is<Identifier>() && static_cast<Identifier&>(*default_value).string() == "yield"sv)
syntax_error("Generator function parameter initializer cannot contain a reference to an identifier named \"yield\"");
if (default_value && is<YieldExpression>(*default_value))
syntax_error("Yield expression not allowed in formal parameter");
}
parameters.append({ move(parameter), default_value, is_rest });
if (match(TokenType::ParenClose))
Expand Down
1 change: 1 addition & 0 deletions Userland/Libraries/LibJS/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ class Parser {
bool allow_super_property_lookup { false };
bool allow_super_constructor_call { false };
bool in_function_context { false };
bool in_formal_parameter_context { false };
bool in_generator_function_context { false };
bool in_arrow_function_context { false };
bool in_break_context { false };
Expand Down
3 changes: 3 additions & 0 deletions Userland/Libraries/LibJS/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ constexpr const u32 NO_BREAK_SPACE { 0x00A0 };
// U+200C ZERO WIDTH NON-JOINER
constexpr const u32 ZERO_WIDTH_NON_JOINER { 0x200C };

// U+FEFF ZERO WIDTH NO-BREAK SPACE
constexpr const u32 ZERO_WIDTH_NO_BREAK_SPACE { 0xFEFF };

// U+200D ZERO WIDTH JOINER
constexpr const u32 ZERO_WIDTH_JOINER { 0x200D };

Expand Down

0 comments on commit c108c8f

Please sign in to comment.