Bug 1929045 - Part 4: Prevent parsing using & await using syntax based on pref. r=arai

Depends on D226993

Differential Revision: https://phabricator.services.mozilla.com/D226994
This commit is contained in:
Debadree Chatterjee 2024-11-12 05:33:15 +00:00
parent 28634b44c5
commit 66ec9c429e
2 changed files with 68 additions and 30 deletions

View File

@ -62,7 +62,10 @@
#include "js/CharacterEncoding.h" // JS::ConstUTF8CharsZ
#include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
#include "js/TypeDecls.h" // JS::MutableHandle (fwd)
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
# include "js/Prefs.h" // JS::Prefs::*
#endif
#include "js/TypeDecls.h" // JS::MutableHandle (fwd)
namespace js {
class FrontendContext;
@ -125,7 +128,12 @@ class JS_PUBLIC_API PrefableCompileOptions {
PrefableCompileOptions()
: importAttributes_(false),
sourcePragmas_(true),
throwOnAsmJSValidationFailure_(false) {}
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
explicitResourceManagement_(
JS::Prefs::experimental_explicit_resource_management()),
#endif
throwOnAsmJSValidationFailure_(false) {
}
bool importAttributes() const { return importAttributes_; }
PrefableCompileOptions& setImportAttributes(bool enabled) {
@ -133,6 +141,16 @@ class JS_PUBLIC_API PrefableCompileOptions {
return *this;
}
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
bool explicitResourceManagement() const {
return explicitResourceManagement_;
}
PrefableCompileOptions& setExplicitResourceManagement(bool enabled) {
explicitResourceManagement_ = enabled;
return *this;
}
#endif
// Enable/disable support for parsing '//(#@) source(Mapping)?URL=' pragmas.
bool sourcePragmas() const { return sourcePragmas_; }
PrefableCompileOptions& setSourcePragmas(bool flag) {
@ -170,6 +188,9 @@ class JS_PUBLIC_API PrefableCompileOptions {
PrintFields_(importAttributes_);
PrintFields_(sourcePragmas_);
PrintFields_(throwOnAsmJSValidationFailure_);
# ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
PrintFields_(explicitResourceManagement_);
# endif
# undef PrintFields_
switch (asmJSOption_) {
@ -199,6 +220,12 @@ class JS_PUBLIC_API PrefableCompileOptions {
// The context has specified that source pragmas should be parsed.
bool sourcePragmas_ : 1;
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
// The context has specified that explicit resource management syntax
// should be parsed.
bool explicitResourceManagement_ : 1;
#endif
// ==== asm.js options. ====
bool throwOnAsmJSValidationFailure_ : 1;
@ -381,6 +408,11 @@ class JS_PUBLIC_API TransitiveCompileOptions {
bool importAttributes() const { return prefableOptions_.importAttributes(); }
bool sourcePragmas() const { return prefableOptions_.sourcePragmas(); }
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
bool explicitResourceManagement() const {
return prefableOptions_.explicitResourceManagement();
}
#endif
bool throwOnAsmJSValidationFailure() const {
return prefableOptions_.throwOnAsmJSValidationFailure();
}

View File

@ -2566,7 +2566,8 @@ bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon(
}
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
if (!this->pc_->isUsingSyntaxAllowed() &&
if (options().explicitResourceManagement() &&
!this->pc_->isUsingSyntaxAllowed() &&
anyChars.currentToken().type == TokenKind::Using) {
error(JSMSG_USING_OUTSIDE_BLOCK_OR_MODULE);
return false;
@ -6534,7 +6535,7 @@ bool GeneralParser<ParseHandler, Unit>::forHeadStart(
tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
}
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
else if (tt == TokenKind::Await) {
else if (tt == TokenKind::Await && options().explicitResourceManagement()) {
if (!pc_->isAsync()) {
if (pc_->atModuleTopLevel()) {
if (!options().topLevelAwait) {
@ -6576,7 +6577,7 @@ bool GeneralParser<ParseHandler, Unit>::forHeadStart(
anyChars.ungetToken(); // put back await token
}
}
} else if (tt == TokenKind::Using) {
} else if (tt == TokenKind::Using && options().explicitResourceManagement()) {
tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
// Look ahead to find either a 'of' token or if not identifier
@ -9659,34 +9660,38 @@ GeneralParser<ParseHandler, Unit>::statementListItem(
if (tt == TokenKind::Await && pc_->isAsync()) {
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
// Try finding evidence of a AwaitUsingDeclaration the syntax for which
// would be:
// await [no LineTerminator here] using [no LineTerminator here]
// identifier
if (options().explicitResourceManagement()) {
// Try finding evidence of a AwaitUsingDeclaration the syntax for
// which
// would be:
// await [no LineTerminator here] using [no LineTerminator here]
// identifier
TokenKind nextTokUsing = TokenKind::Eof;
// Scan with regex modifier because when its await expression, `/`
// should be treated as a regexp.
if (!tokenStream.peekTokenSameLine(&nextTokUsing,
TokenStream::SlashIsRegExp)) {
return errorResult();
}
if (nextTokUsing == TokenKind::Using &&
this->pc_->isUsingSyntaxAllowed()) {
tokenStream.consumeKnownToken(nextTokUsing,
TokenStream::SlashIsRegExp);
TokenKind nextTokIdentifier = TokenKind::Eof;
// Here we can use the Div modifier because if the next token is using
// then a `/` as the next token can only be considered a division.
if (!tokenStream.peekTokenSameLine(&nextTokIdentifier)) {
TokenKind nextTokUsing = TokenKind::Eof;
// Scan with regex modifier because when its await expression, `/`
// should be treated as a regexp.
if (!tokenStream.peekTokenSameLine(&nextTokUsing,
TokenStream::SlashIsRegExp)) {
return errorResult();
}
if (TokenKindIsPossibleIdentifier(nextTokIdentifier)) {
return lexicalDeclaration(yieldHandling,
DeclarationKind::AwaitUsing);
if (nextTokUsing == TokenKind::Using &&
this->pc_->isUsingSyntaxAllowed()) {
tokenStream.consumeKnownToken(nextTokUsing,
TokenStream::SlashIsRegExp);
TokenKind nextTokIdentifier = TokenKind::Eof;
// Here we can use the Div modifier because if the next token is
// using then a `/` as the next token can only be considered a
// division.
if (!tokenStream.peekTokenSameLine(&nextTokIdentifier)) {
return errorResult();
}
if (TokenKindIsPossibleIdentifier(nextTokIdentifier)) {
return lexicalDeclaration(yieldHandling,
DeclarationKind::AwaitUsing);
}
anyChars.ungetToken(); // put back using.
}
anyChars.ungetToken(); // put back using.
}
#endif
return expressionStatement(yieldHandling);
@ -9815,7 +9820,8 @@ GeneralParser<ParseHandler, Unit>::statementListItem(
if (!tokenStream.peekTokenSameLine(&nextTok)) {
return errorResult();
}
if (!TokenKindIsPossibleIdentifier(nextTok) ||
if (!options().explicitResourceManagement() ||
!TokenKindIsPossibleIdentifier(nextTok) ||
!this->pc_->isUsingSyntaxAllowed()) {
if (!tokenStream.peekToken(&nextTok)) {
return errorResult();