Commit 5efc6b59 authored by andersca@apple.com's avatar andersca@apple.com

WebCore: <rdar://problem/7007541>

CrashTracer: 4800+ crashes in Safari at com.apple.WebKit • WTF::HashTableIterator...
        
Reviewed by Oliver Hunt.

Make RuntimeObjectImp more robust against m_instance being a null (which can happen if an OOP plug-in
crashes while we're calling into it).
        
* bridge/runtime_object.cpp:
(JSC::RuntimeObjectImp::RuntimeObjectImp):
(JSC::RuntimeObjectImp::~RuntimeObjectImp):
(JSC::RuntimeObjectImp::invalidate):
(JSC::RuntimeObjectImp::fallbackObjectGetter):
(JSC::RuntimeObjectImp::fieldGetter):
(JSC::RuntimeObjectImp::methodGetter):
(JSC::RuntimeObjectImp::getOwnPropertySlot):
(JSC::RuntimeObjectImp::getOwnPropertyDescriptor):
(JSC::RuntimeObjectImp::put):
(JSC::RuntimeObjectImp::defaultValue):
(JSC::RuntimeObjectImp::getCallData):
(JSC::RuntimeObjectImp::getConstructData):
(JSC::RuntimeObjectImp::getPropertyNames):
* bridge/runtime_object.h:
(JSC::RuntimeObjectImp::getInternalInstance):

WebKit/mac: <rdar://problem/7007541> 
CrashTracer: 4800+ crashes in Safari at com.apple.WebKit • WTF::HashTableIterator...

Reviewed by Oliver Hunt.

Add null checks for m_instanceProxy (It will be null when a plug-in has crashed).
        
* Plugins/Hosted/ProxyInstance.mm:
(WebKit::ProxyInstance::invoke):
(WebKit::ProxyInstance::supportsInvokeDefaultMethod):
(WebKit::ProxyInstance::supportsConstruct):
(WebKit::ProxyInstance::getPropertyNames):
(WebKit::ProxyInstance::methodsNamed):
(WebKit::ProxyInstance::fieldNamed):
(WebKit::ProxyInstance::fieldValue):
(WebKit::ProxyInstance::setFieldValue):
(WebKit::ProxyInstance::invalidate):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@48492 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 703a517d
2009-09-17 Anders Carlsson <andersca@apple.com>
Reviewed by Oliver Hunt.
<rdar://problem/7007541>
CrashTracer: 4800+ crashes in Safari at com.apple.WebKit • WTF::HashTableIterator...
Make RuntimeObjectImp more robust against m_instance being a null (which can happen if an OOP plug-in
crashes while we're calling into it).
* bridge/runtime_object.cpp:
(JSC::RuntimeObjectImp::RuntimeObjectImp):
(JSC::RuntimeObjectImp::~RuntimeObjectImp):
(JSC::RuntimeObjectImp::invalidate):
(JSC::RuntimeObjectImp::fallbackObjectGetter):
(JSC::RuntimeObjectImp::fieldGetter):
(JSC::RuntimeObjectImp::methodGetter):
(JSC::RuntimeObjectImp::getOwnPropertySlot):
(JSC::RuntimeObjectImp::getOwnPropertyDescriptor):
(JSC::RuntimeObjectImp::put):
(JSC::RuntimeObjectImp::defaultValue):
(JSC::RuntimeObjectImp::getCallData):
(JSC::RuntimeObjectImp::getConstructData):
(JSC::RuntimeObjectImp::getPropertyNames):
* bridge/runtime_object.h:
(JSC::RuntimeObjectImp::getInternalInstance):
2009-09-17 Yury Semikhatsky <yurys@chromium.org>
Reviewed by Timothy Hatcher.
......@@ -40,38 +40,38 @@ using namespace Bindings;
const ClassInfo RuntimeObjectImp::s_info = { "RuntimeObject", 0, 0, 0 };
RuntimeObjectImp::RuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> i)
RuntimeObjectImp::RuntimeObjectImp(ExecState* exec, PassRefPtr<Instance> instance)
// FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object
// We need to pass in the right global object for "i".
: JSObject(deprecatedGetDOMStructure<RuntimeObjectImp>(exec))
, instance(i)
, m_instance(instance)
{
instance->rootObject()->addRuntimeObject(this);
m_instance->rootObject()->addRuntimeObject(this);
}
RuntimeObjectImp::RuntimeObjectImp(ExecState*, PassRefPtr<Structure> structure, PassRefPtr<Instance> i)
RuntimeObjectImp::RuntimeObjectImp(ExecState*, PassRefPtr<Structure> structure, PassRefPtr<Instance> instance)
: JSObject(structure)
, instance(i)
, m_instance(instance)
{
instance->rootObject()->addRuntimeObject(this);
m_instance->rootObject()->addRuntimeObject(this);
}
RuntimeObjectImp::~RuntimeObjectImp()
{
if (instance)
instance->rootObject()->removeRuntimeObject(this);
if (m_instance)
m_instance->rootObject()->removeRuntimeObject(this);
}
void RuntimeObjectImp::invalidate()
{
ASSERT(instance);
instance = 0;
ASSERT(m_instance);
m_instance = 0;
}
JSValue RuntimeObjectImp::fallbackObjectGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase()));
RefPtr<Instance> instance = thisObj->instance;
RefPtr<Instance> instance = thisObj->m_instance;
if (!instance)
return throwInvalidAccessError(exec);
......@@ -89,7 +89,7 @@ JSValue RuntimeObjectImp::fallbackObjectGetter(ExecState* exec, const Identifier
JSValue RuntimeObjectImp::fieldGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase()));
RefPtr<Instance> instance = thisObj->instance;
RefPtr<Instance> instance = thisObj->m_instance;
if (!instance)
return throwInvalidAccessError(exec);
......@@ -108,7 +108,7 @@ JSValue RuntimeObjectImp::fieldGetter(ExecState* exec, const Identifier& propert
JSValue RuntimeObjectImp::methodGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
RuntimeObjectImp* thisObj = static_cast<RuntimeObjectImp*>(asObject(slot.slotBase()));
RefPtr<Instance> instance = thisObj->instance;
RefPtr<Instance> instance = thisObj->m_instance;
if (!instance)
return throwInvalidAccessError(exec);
......@@ -126,11 +126,13 @@ JSValue RuntimeObjectImp::methodGetter(ExecState* exec, const Identifier& proper
bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
if (!instance) {
if (!m_instance) {
throwInvalidAccessError(exec);
return false;
}
RefPtr<Instance> instance = m_instance;
instance->begin();
Class *aClass = instance->getClass();
......@@ -169,11 +171,12 @@ bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& pro
bool RuntimeObjectImp::getOwnPropertyDescriptor(ExecState *exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
if (!instance) {
if (!m_instance) {
throwInvalidAccessError(exec);
return false;
}
RefPtr<Instance> instance = m_instance;
instance->begin();
Class *aClass = instance->getClass();
......@@ -217,12 +220,12 @@ bool RuntimeObjectImp::getOwnPropertyDescriptor(ExecState *exec, const Identifie
void RuntimeObjectImp::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
if (!instance) {
if (!m_instance) {
throwInvalidAccessError(exec);
return;
}
RefPtr<Instance> protector(instance);
RefPtr<Instance> instance = m_instance;
instance->begin();
// Set the value of the property.
......@@ -243,10 +246,11 @@ bool RuntimeObjectImp::deleteProperty(ExecState*, const Identifier&)
JSValue RuntimeObjectImp::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
{
if (!instance)
if (!m_instance)
return throwInvalidAccessError(exec);
RefPtr<Instance> protector(instance);
RefPtr<Instance> instance = m_instance;
instance->begin();
JSValue result = instance->defaultValue(exec, hint);
instance->end();
......@@ -264,8 +268,13 @@ static JSValue JSC_HOST_CALL callRuntimeObject(ExecState* exec, JSObject* functi
CallType RuntimeObjectImp::getCallData(CallData& callData)
{
if (!instance || !instance->supportsInvokeDefaultMethod())
if (!m_instance)
return CallTypeNone;
RefPtr<Instance> instance = m_instance;
if (!instance->supportsInvokeDefaultMethod())
return CallTypeNone;
callData.native.function = callRuntimeObject;
return CallTypeHost;
}
......@@ -283,19 +292,26 @@ static JSObject* callRuntimeConstructor(ExecState* exec, JSObject* constructor,
ConstructType RuntimeObjectImp::getConstructData(ConstructData& constructData)
{
if (!instance || !instance->supportsConstruct())
if (!m_instance)
return ConstructTypeNone;
RefPtr<Instance> instance = m_instance;
if (!instance->supportsConstruct())
return ConstructTypeNone;
constructData.native.function = callRuntimeConstructor;
return ConstructTypeHost;
}
void RuntimeObjectImp::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
if (!instance) {
if (!m_instance) {
throwInvalidAccessError(exec);
return;
}
RefPtr<Instance> instance = m_instance;
instance->begin();
instance->getPropertyNames(exec, propertyNames);
instance->end();
......
......@@ -49,7 +49,7 @@ public:
virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&);
virtual void invalidate();
Bindings::Instance* getInternalInstance() const { return instance.get(); }
Bindings::Instance* getInternalInstance() const { return m_instance.get(); }
static JSObject* throwInvalidAccessError(ExecState*);
......@@ -75,7 +75,7 @@ private:
static JSValue fieldGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue methodGetter(ExecState*, const Identifier&, const PropertySlot&);
RefPtr<Bindings::Instance> instance;
RefPtr<Bindings::Instance> m_instance;
};
} // namespace
......
2009-09-17 Anders Carlsson <andersca@apple.com>
Reviewed by Oliver Hunt.
<rdar://problem/7007541>
CrashTracer: 4800+ crashes in Safari at com.apple.WebKit • WTF::HashTableIterator...
Add null checks for m_instanceProxy (It will be null when a plug-in has crashed).
* Plugins/Hosted/ProxyInstance.mm:
(WebKit::ProxyInstance::invoke):
(WebKit::ProxyInstance::supportsInvokeDefaultMethod):
(WebKit::ProxyInstance::supportsConstruct):
(WebKit::ProxyInstance::getPropertyNames):
(WebKit::ProxyInstance::methodsNamed):
(WebKit::ProxyInstance::fieldNamed):
(WebKit::ProxyInstance::fieldValue):
(WebKit::ProxyInstance::setFieldValue):
(WebKit::ProxyInstance::invalidate):
2009-09-16 Simon Fraser <simon.fraser@apple.com>
Reviewed by Dan Bernstein.
......
......@@ -136,6 +136,9 @@ JSC::Bindings::Class *ProxyInstance::getClass() const
JSValue ProxyInstance::invoke(JSC::ExecState* exec, InvokeType type, uint64_t identifier, const JSC::ArgList& args)
{
if (!m_instanceProxy)
return jsUndefined();
RetainPtr<NSData*> arguments(m_instanceProxy->marshalValues(exec, args));
uint32_t requestID = m_instanceProxy->nextRequestID();
......@@ -162,6 +165,9 @@ JSValue ProxyInstance::invokeMethod(ExecState* exec, const MethodList& methodLis
bool ProxyInstance::supportsInvokeDefaultMethod() const
{
if (!m_instanceProxy)
return false;
uint32_t requestID = m_instanceProxy->nextRequestID();
if (_WKPHNPObjectHasInvokeDefaultMethod(m_instanceProxy->hostProxy()->port(),
......@@ -183,6 +189,9 @@ JSValue ProxyInstance::invokeDefaultMethod(ExecState* exec, const ArgList& args)
bool ProxyInstance::supportsConstruct() const
{
if (!m_instanceProxy)
return false;
uint32_t requestID = m_instanceProxy->nextRequestID();
if (_WKPHNPObjectHasConstructMethod(m_instanceProxy->hostProxy()->port(),
......@@ -236,6 +245,9 @@ JSValue ProxyInstance::valueOf(ExecState* exec) const
void ProxyInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArray)
{
if (!m_instanceProxy)
return;
uint32_t requestID = m_instanceProxy->nextRequestID();
if (_WKPHNPObjectEnumerate(m_instanceProxy->hostProxy()->port(), m_instanceProxy->pluginID(), requestID, m_objectID) != KERN_SUCCESS)
......@@ -266,6 +278,9 @@ void ProxyInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArr
MethodList ProxyInstance::methodsNamed(const Identifier& identifier)
{
if (!m_instanceProxy)
return MethodList();
// If we already have an entry in the map, use it.
MethodMap::iterator existingMapEntry = m_methods.find(identifier.ustring().rep());
if (existingMapEntry != m_methods.end()) {
......@@ -303,6 +318,9 @@ MethodList ProxyInstance::methodsNamed(const Identifier& identifier)
Field* ProxyInstance::fieldNamed(const Identifier& identifier)
{
if (!m_instanceProxy)
return 0;
// If we already have an entry in the map, use it.
FieldMap::iterator existingMapEntry = m_fields.find(identifier.ustring().rep());
if (existingMapEntry != m_fields.end())
......@@ -332,6 +350,9 @@ Field* ProxyInstance::fieldNamed(const Identifier& identifier)
JSC::JSValue ProxyInstance::fieldValue(ExecState* exec, const Field* field) const
{
if (!m_instanceProxy)
return jsUndefined();
uint64_t serverIdentifier = static_cast<const ProxyField*>(field)->serverIdentifier();
uint32_t requestID = m_instanceProxy->nextRequestID();
......@@ -349,6 +370,9 @@ JSC::JSValue ProxyInstance::fieldValue(ExecState* exec, const Field* field) cons
void ProxyInstance::setFieldValue(ExecState* exec, const Field* field, JSValue value) const
{
if (m_instanceProxy)
return;
uint64_t serverIdentifier = static_cast<const ProxyField*>(field)->serverIdentifier();
uint32_t requestID = m_instanceProxy->nextRequestID();
......@@ -368,6 +392,8 @@ void ProxyInstance::setFieldValue(ExecState* exec, const Field* field, JSValue v
void ProxyInstance::invalidate()
{
ASSERT(m_instanceProxy);
if (NetscapePluginHostProxy* hostProxy = m_instanceProxy->hostProxy())
_WKPHNPObjectRelease(hostProxy->port(),
m_instanceProxy->pluginID(), m_objectID);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment