diff options
author | Martok <martok@martoks-place.de> | 2023-04-09 19:56:58 +0200 |
---|---|---|
committer | Martok <martok@martoks-place.de> | 2023-05-01 17:16:18 +0200 |
commit | 98853c14d7ac07ad046395c600b93f3eda444919 (patch) | |
tree | 2656e3d3e7580caedc8aa7feec582ab73684f1dd | |
parent | e708a68921c44c396502fda9849078f8b983f343 (diff) | |
download | uxp-98853c14d7ac07ad046395c600b93f3eda444919.tar.gz |
Issue #2142 - Restrict contents of direct eval in fields
Based-on: m-c 1542406
-rw-r--r-- | js/src/frontend/Parser.cpp | 24 | ||||
-rw-r--r-- | js/src/frontend/Parser.h | 5 | ||||
-rw-r--r-- | js/src/vm/Scope.cpp | 15 | ||||
-rw-r--r-- | js/src/vm/Scope.h | 12 |
4 files changed, 42 insertions, 14 deletions
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index bd7dc40bf7..bc60503b25 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -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)) diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index f29d5aaeed..5222d6398c 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -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); diff --git a/js/src/vm/Scope.cpp b/js/src/vm/Scope.cpp index 5cb9abaecf..870add219f 100644 --- a/js/src/vm/Scope.cpp +++ b/js/src/vm/Scope.cpp @@ -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; diff --git a/js/src/vm/Scope.h b/js/src/vm/Scope.h index fc1419bb89..a1e52e3800 100644 --- a/js/src/vm/Scope.h +++ b/js/src/vm/Scope.h @@ -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; } |