Bug 1283448 - Freeze module objects before they are passed back to the caller r=shu

This commit is contained in:
Jon Coppeard 2016-07-05 11:31:28 +01:00
Родитель 30cb0bf87f
Коммит 82ee97156b
5 изменённых файлов: 44 добавлений и 22 удалений

Просмотреть файл

@ -722,36 +722,46 @@ FreezeObjectProperty(JSContext* cx, HandleNativeObject obj, uint32_t slot)
}
/* static */ bool
ModuleObject::FreezeArrayProperties(JSContext* cx, HandleModuleObject self)
ModuleObject::Freeze(JSContext* cx, HandleModuleObject self)
{
return FreezeObjectProperty(cx, self, RequestedModulesSlot) &&
FreezeObjectProperty(cx, self, ImportEntriesSlot) &&
FreezeObjectProperty(cx, self, LocalExportEntriesSlot) &&
FreezeObjectProperty(cx, self, IndirectExportEntriesSlot) &&
FreezeObjectProperty(cx, self, StarExportEntriesSlot);
FreezeObjectProperty(cx, self, StarExportEntriesSlot) &&
FreezeObject(cx, self);
}
static inline void
AssertObjectPropertyFrozen(JSContext* cx, HandleNativeObject obj, uint32_t slot)
{
#ifdef DEBUG
static inline bool
IsObjectFrozen(JSContext* cx, HandleObject obj)
{
bool frozen = false;
RootedObject property(cx, &obj->getSlot(slot).toObject());
MOZ_ALWAYS_TRUE(TestIntegrityLevel(cx, property, IntegrityLevel::Frozen, &frozen));
MOZ_ASSERT(frozen);
#endif
MOZ_ALWAYS_TRUE(TestIntegrityLevel(cx, obj, IntegrityLevel::Frozen, &frozen));
return frozen;
}
/* static */ inline void
ModuleObject::AssertArrayPropertiesFrozen(JSContext* cx, HandleModuleObject self)
static inline bool
IsObjectPropertyFrozen(JSContext* cx, HandleNativeObject obj, uint32_t slot)
{
AssertObjectPropertyFrozen(cx, self, RequestedModulesSlot);
AssertObjectPropertyFrozen(cx, self, ImportEntriesSlot);
AssertObjectPropertyFrozen(cx, self, LocalExportEntriesSlot);
AssertObjectPropertyFrozen(cx, self, IndirectExportEntriesSlot);
AssertObjectPropertyFrozen(cx, self, StarExportEntriesSlot);
RootedObject property(cx, &obj->getSlot(slot).toObject());
return IsObjectFrozen(cx, property);
}
/* static */ inline bool
ModuleObject::IsFrozen(JSContext* cx, HandleModuleObject self)
{
return IsObjectPropertyFrozen(cx, self, RequestedModulesSlot) &&
IsObjectPropertyFrozen(cx, self, ImportEntriesSlot) &&
IsObjectPropertyFrozen(cx, self, LocalExportEntriesSlot) &&
IsObjectPropertyFrozen(cx, self, IndirectExportEntriesSlot) &&
IsObjectPropertyFrozen(cx, self, StarExportEntriesSlot) &&
IsObjectFrozen(cx, self);
}
#endif
inline static void
AssertModuleScopesMatch(ModuleObject* module)
{
@ -858,7 +868,7 @@ ModuleObject::noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, Han
/* static */ bool
ModuleObject::instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject self)
{
AssertArrayPropertiesFrozen(cx, self);
MOZ_ASSERT(IsFrozen(cx, self));
FunctionDeclarationVector* funDecls = self->functionDeclarations();
if (!funDecls) {
@ -896,7 +906,7 @@ ModuleObject::setEvaluated()
/* static */ bool
ModuleObject::evaluate(JSContext* cx, HandleModuleObject self, MutableHandleValue rval)
{
AssertArrayPropertiesFrozen(cx, self);
MOZ_ASSERT(IsFrozen(cx, self));
RootedScript script(cx, self->script());
RootedModuleEnvironmentObject scope(cx, self->environment());

Просмотреть файл

@ -236,8 +236,10 @@ class ModuleObject : public NativeObject
HandleArrayObject localExportEntries,
HandleArrayObject indiretExportEntries,
HandleArrayObject starExportEntries);
static bool FreezeArrayProperties(JSContext* cx, HandleModuleObject self);
static void AssertArrayPropertiesFrozen(JSContext* cx, HandleModuleObject self);
static bool Freeze(JSContext* cx, HandleModuleObject self);
#ifdef DEBUG
static bool IsFrozen(JSContext* cx, HandleModuleObject self);
#endif
void fixScopesAfterCompartmentMerge(JSContext* cx);
JSScript* script() const;

Просмотреть файл

@ -801,7 +801,7 @@ frontend::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
// This happens in GlobalHelperThreadState::finishModuleParseTask() when a
// module is compiled off main thread.
if (!ModuleObject::FreezeArrayProperties(cx->asJSContext(), module))
if (!ModuleObject::Freeze(cx->asJSContext(), module))
return nullptr;
return module;

Просмотреть файл

@ -0,0 +1,10 @@
// |jit-test| error: TypeError
let moduleRepo = {};
setModuleResolveHook(function(module, specifier) {
return moduleRepo[specifier];
});
let a = moduleRepo['a'] = parseModule("var x = 1; export { x };");
let b = moduleRepo['b'] = parseModule("import { x as y } from 'a';");
a.__proto__ = {15: 1337};
b.declarationInstantiation();

Просмотреть файл

@ -1215,7 +1215,7 @@ GlobalHelperThreadState::finishModuleParseTask(JSContext* maybecx, JSRuntime* rt
JSContext* cx = maybecx;
RootedModuleObject module(cx, script->module());
module->fixScopesAfterCompartmentMerge(cx);
if (!ModuleObject::FreezeArrayProperties(cx, module))
if (!ModuleObject::Freeze(cx, module))
return nullptr;
return module;