Issue #2142 - Restrict contents of direct eval in fields

Based-on: m-c 1542406
This commit is contained in:
Martok 2023-04-09 19:56:58 +02:00 committed by roytam1
commit 8c6750014c
4 changed files with 42 additions and 14 deletions

View file

@ -214,12 +214,18 @@ SharedContext::computeAllowSyntax(Scope* scope)
{
for (ScopeIter si(scope); si; si++) {
if (si.kind() == ScopeKind::Function) {
JSFunction* fun = si.scope()->as<FunctionScope>().canonicalFunction();
FunctionScope* funScope = &si.scope()->as<FunctionScope>();
JSFunction* fun = funScope->canonicalFunction();
if (fun->isArrow())
continue;
allowNewTarget_ = true;
allowSuperProperty_ = fun->allowSuperProperty();
allowSuperCall_ = fun->isDerivedClassConstructor();
if (funScope->isFieldInitializer()) {
allowSuperProperty_ = false;
allowSuperCall_ = false;
allowArguments_ = false;
}
return;
}
}
@ -1881,7 +1887,8 @@ Parser<FullParseHandler>::newEvalScopeData(ParseContext::Scope& scope)
template <>
Maybe<FunctionScope::Data*>
Parser<FullParseHandler>::newFunctionScopeData(ParseContext::Scope& scope, bool hasParameterExprs)
Parser<FullParseHandler>::newFunctionScopeData(ParseContext::Scope& scope, bool hasParameterExprs,
bool isFieldInitializer)
{
Vector<BindingName> positionalFormals(context);
Vector<BindingName> formals(context);
@ -1955,6 +1962,8 @@ Parser<FullParseHandler>::newFunctionScopeData(ParseContext::Scope& scope, bool
if (!bindings)
return Nothing();
bindings->isFieldInitializer = isFieldInitializer;
// The ordering here is important. See comments in FunctionScope.
BindingName* start = bindings->trailingNames.start();
BindingName* cursor = start;
@ -2403,7 +2412,8 @@ Parser<ParseHandler>::finishFunctionScopes(bool isStandaloneFunction)
template <>
bool
Parser<FullParseHandler>::finishFunction(bool isStandaloneFunction /* = false */)
Parser<FullParseHandler>::finishFunction(bool isStandaloneFunction /* = false */,
bool isFieldInitializer /* = false */)
{
if (!finishFunctionScopes(isStandaloneFunction))
return false;
@ -2420,7 +2430,8 @@ Parser<FullParseHandler>::finishFunction(bool isStandaloneFunction /* = false */
{
Maybe<FunctionScope::Data*> bindings = newFunctionScopeData(pc->functionScope(),
hasParameterExprs);
hasParameterExprs,
isFieldInitializer);
if (!bindings)
return false;
funbox->functionScopeBindings().set(*bindings);
@ -2438,7 +2449,8 @@ Parser<FullParseHandler>::finishFunction(bool isStandaloneFunction /* = false */
template <>
bool
Parser<SyntaxParseHandler>::finishFunction(bool isStandaloneFunction /* = false */)
Parser<SyntaxParseHandler>::finishFunction(bool isStandaloneFunction /* = false */,
bool isFieldInitializer /* = false */)
{
// The LazyScript for a lazily parsed function needs to know its set of
// free variables and inner functions so that when it is fully parsed, we
@ -8076,7 +8088,7 @@ Parser<ParseHandler>::fieldInitializerOpt(YieldHandling yieldHandling, bool hasH
handler.setFunctionBody(funNode, initializerBody);
if (!finishFunction())
if (!finishFunction(false, true))
return null();
if (!leaveInnerFunction(outerpc))

View file

@ -1572,7 +1572,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
bool finishFunctionScopes(bool isStandaloneFunction);
bool finishFunction(bool isStandaloneFunction = false);
bool finishFunction(bool isStandaloneFunction = false, bool isFieldInitializer = false);
bool leaveInnerFunction(ParseContext* outerpc);
bool matchOrInsertSemicolonHelper(TokenStream::Modifier modifier);
@ -1620,7 +1620,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
mozilla::Maybe<ModuleScope::Data*> newModuleScopeData(ParseContext::Scope& scope);
mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope);
mozilla::Maybe<FunctionScope::Data*> newFunctionScopeData(ParseContext::Scope& scope,
bool hasParameterExprs);
bool hasParameterExprs,
bool isFieldInitializer);
mozilla::Maybe<VarScope::Data*> newVarScopeData(ParseContext::Scope& scope);
mozilla::Maybe<LexicalScope::Data*> newLexicalScopeData(ParseContext::Scope& scope);
LexicalScopeNodeType finishLexicalScope(ParseContext::Scope& scope, Node body);

View file

@ -610,12 +610,14 @@ FunctionScope::create(ExclusiveContext* cx, Handle<Data*> dataArg,
if (!data)
return nullptr;
return createWithData(cx, &data, hasParameterExprs, needsEnvironment, fun, enclosing);
return createWithData(cx, &data, hasParameterExprs, dataArg ? dataArg->isFieldInitializer : false,
needsEnvironment, fun, enclosing);
}
/* static */ FunctionScope*
FunctionScope::createWithData(ExclusiveContext* cx, MutableHandle<UniquePtr<Data>> data,
bool hasParameterExprs, bool needsEnvironment,
bool hasParameterExprs, bool isFieldInitializer,
bool needsEnvironment,
HandleFunction fun, HandleScope enclosing)
{
MOZ_ASSERT(data);
@ -636,6 +638,7 @@ FunctionScope::createWithData(ExclusiveContext* cx, MutableHandle<UniquePtr<Data
return nullptr;
}
data->isFieldInitializer = isFieldInitializer;
data->hasParameterExprs = hasParameterExprs;
data->canonicalFunction.init(fun);
@ -737,16 +740,20 @@ FunctionScope::XDR(XDRState<mode>* xdr, HandleFunction fun, HandleScope enclosin
uint8_t needsEnvironment;
uint8_t hasParameterExprs;
uint8_t isFieldInitializer;
uint32_t nextFrameSlot;
if (mode == XDR_ENCODE) {
needsEnvironment = scope->hasEnvironment();
hasParameterExprs = data->hasParameterExprs;
isFieldInitializer = data->isFieldInitializer;
nextFrameSlot = data->nextFrameSlot;
}
if (!xdr->codeUint8(&needsEnvironment))
return false;
if (!xdr->codeUint8(&hasParameterExprs))
return false;
if (!xdr->codeUint8(&isFieldInitializer))
return false;
if (!xdr->codeUint16(&data->nonPositionalFormalStart))
return false;
if (!xdr->codeUint16(&data->varStart))
@ -761,8 +768,8 @@ FunctionScope::XDR(XDRState<mode>* xdr, HandleFunction fun, HandleScope enclosin
MOZ_ASSERT(!data->nextFrameSlot);
}
scope.set(createWithData(cx, &uniqueData.ref(), hasParameterExprs, needsEnvironment, fun,
enclosing));
scope.set(createWithData(cx, &uniqueData.ref(), hasParameterExprs, !!isFieldInitializer,
needsEnvironment, fun, enclosing));
if (!scope)
return false;

View file

@ -500,6 +500,9 @@ class FunctionScope : public Scope
// bindings.
bool hasParameterExprs = false;
// Anonymous functions used in field initializers are limited.
bool isFieldInitializer = false;
// Bindings are sorted by kind in both frames and environments.
//
// Positional formal parameter names are those that are not
@ -548,8 +551,9 @@ class FunctionScope : public Scope
private:
static FunctionScope* createWithData(ExclusiveContext* cx, MutableHandle<UniquePtr<Data>> data,
bool hasParameterExprs, bool needsEnvironment,
HandleFunction fun, HandleScope enclosing);
bool hasParameterExprs, bool isFieldInitializer,
bool needsEnvironment, HandleFunction fun,
HandleScope enclosing);
Data& data() {
return *reinterpret_cast<Data*>(data_);
@ -574,6 +578,10 @@ class FunctionScope : public Scope
return data().hasParameterExprs;
}
bool isFieldInitializer() const {
return data().isFieldInitializer;
}
uint32_t numPositionalFormalParameters() const {
return data().nonPositionalFormalStart;
}