Issue #2142 - Ensure 'await' is always a restricted identifier when parsing modules

Based-on: m-c 1356189
This commit is contained in:
Martok 2023-04-26 18:21:35 +02:00 committed by roytam1
commit faed047e3f
2 changed files with 38 additions and 21 deletions

View file

@ -785,7 +785,7 @@ ParserBase::ParserBase(ExclusiveContext* cx, LifoAlloc& alloc,
#endif
abortedSyntaxParse(false),
isUnexpectedEOF_(false),
awaitIsKeyword_(false),
awaitHandling_(AwaitIsName),
parseGoal_(uint8_t(parseGoal))
{
cx->perThreadData->frontendCollectionPool.addActiveCompilation();
@ -846,18 +846,18 @@ Parser<ParseHandler>::~Parser()
template <>
void
Parser<SyntaxParseHandler>::setAwaitIsKeyword(bool isKeyword)
Parser<SyntaxParseHandler>::setAwaitHandling(AwaitHandling awaitHandling)
{
awaitIsKeyword_ = isKeyword;
awaitHandling_ = awaitHandling;
}
template <>
void
Parser<FullParseHandler>::setAwaitIsKeyword(bool isKeyword)
Parser<FullParseHandler>::setAwaitHandling(AwaitHandling awaitHandling)
{
awaitIsKeyword_ = isKeyword;
awaitHandling_ = awaitHandling;
if (Parser<SyntaxParseHandler>* parser = handler.syntaxParser)
parser->setAwaitIsKeyword(isKeyword);
parser->setAwaitHandling(awaitHandling);
}
template <typename ParseHandler>
@ -2217,7 +2217,7 @@ Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc)
if (!moduleNode)
return null();
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, true);
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, AwaitIsModuleKeyword);
ListNode* stmtList = statementList(YieldIsName);
if (!stmtList) {
return null();
@ -2490,6 +2490,14 @@ GetYieldHandling(GeneratorKind generatorKind)
return YieldIsKeyword;
}
static AwaitHandling
GetAwaitHandling(FunctionAsyncKind asyncKind)
{
if (asyncKind == SyncFunction)
return AwaitIsName;
return AwaitIsKeyword;
}
template <>
FunctionNode*
Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
@ -2549,7 +2557,8 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
funpc.setIsStandaloneFunctionBody();
YieldHandling yieldHandling = GetYieldHandling(generatorKind);
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, asyncKind == AsyncFunction);
AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, awaitHandling);
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, FunctionSyntaxKind::Statement,
parameterListEnd, /* isStandaloneFunction = */ true))
{
@ -3641,9 +3650,11 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
// See below for an explanation why arrow function parameters and arrow
// function bodies are parsed with different yield/await settings.
{
bool asyncOrArrowInAsync = funbox->isAsync() ||
(kind == FunctionSyntaxKind::Arrow && awaitIsKeyword());
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, asyncOrArrowInAsync);
AwaitHandling awaitHandling = funbox->isAsync() ||
(kind == FunctionSyntaxKind::Arrow && awaitIsKeyword())
? AwaitIsKeyword
: AwaitIsName;
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, awaitHandling);
if (!functionArguments(yieldHandling, kind, funNode))
return false;
}
@ -3713,9 +3724,10 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
// Whereas the |yield| in the function body is always parsed as a name.
// The same goes when parsing |await| in arrow functions.
YieldHandling bodyYieldHandling = GetYieldHandling(pc->generatorKind());
AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc->asyncKind());
LexicalScopeNodeType body;
{
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, funbox->isAsync());
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, bodyAwaitHandling);
body = functionBody(inHandling, bodyYieldHandling, kind, bodyType);
if (!body)
return false;
@ -3873,7 +3885,7 @@ Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction inv
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION));
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, asyncKind == AsyncFunction);
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, GetAwaitHandling(asyncKind));
GeneratorKind generatorKind = NotGenerator;
TokenKind tt;
if (!tokenStream.getToken(&tt))

View file

@ -591,6 +591,7 @@ enum class PropertyType {
// we're in a function box -- easier and simpler than passing an extra
// parameter everywhere.
enum YieldHandling { YieldIsName, YieldIsKeyword };
enum AwaitHandling : uint8_t { AwaitIsName, AwaitIsKeyword, AwaitIsModuleKeyword };
enum InHandling { InAllowed, InProhibited };
enum DefaultHandling { NameRequired, AllowDefaultName };
enum TripledotHandling { TripledotAllowed, TripledotProhibited };
@ -800,13 +801,13 @@ class ParserBase : public StrictModeGetter
/* Unexpected end of input, i.e. TOK_EOF not at top-level. */
bool isUnexpectedEOF_:1;
bool awaitIsKeyword_:1;
/* AwaitHandling */ uint8_t awaitHandling_:2;
uint8_t parseGoal_:1;
public:
bool awaitIsKeyword() const {
return awaitIsKeyword_;
return awaitHandling_ != AwaitIsName;
}
ParseGoal parseGoal() const {
@ -1058,7 +1059,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
~Parser();
friend class AutoAwaitIsKeyword<ParseHandler>;
void setAwaitIsKeyword(bool isKeyword);
void setAwaitHandling(AwaitHandling awaitHandling);
bool checkOptions();
@ -1643,17 +1644,21 @@ class MOZ_STACK_CLASS AutoAwaitIsKeyword
{
private:
Parser<ParseHandler>* parser_;
bool oldAwaitIsKeyword_;
AwaitHandling oldAwaitHandling_;
public:
AutoAwaitIsKeyword(Parser<ParseHandler>* parser, bool awaitIsKeyword) {
AutoAwaitIsKeyword(Parser<ParseHandler>* parser, AwaitHandling awaitHandling) {
parser_ = parser;
oldAwaitIsKeyword_ = parser_->awaitIsKeyword_;
parser_->setAwaitIsKeyword(awaitIsKeyword);
oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
// 'await' is always a keyword in module contexts, so we don't modify
// the state when the original handling is AwaitIsModuleKeyword.
if (oldAwaitHandling_ != AwaitIsModuleKeyword)
parser_->setAwaitHandling(awaitHandling);
}
~AutoAwaitIsKeyword() {
parser_->setAwaitIsKeyword(oldAwaitIsKeyword_);
parser_->setAwaitHandling(oldAwaitHandling_);
}
};