[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.22-985-g3c00f00

barraclough at apple.com barraclough at apple.com
Wed Mar 17 18:03:29 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 8c50dfcd0cee4ed63d93158684ef0b5a2b3999a7
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Feb 26 22:21:37 2010 +0000

    Bug 35401 - Fix handling of errors in handling calls over bridge,
    where base object bridge-type does not match method bridge-type.
    
    Reviewed by Alexey Proskuryakov.
    
    The code assumes users will only attempt to invoke a Java method
    on a Java base object, etc.
    Add language specific subclasses of RuntimeMethod, and pass the
    RuntimeMethod into invokeMethod, so we can typecheck before
    casting.  Throw an exception on type mismatch.
    
    WebCore:
    
    * WebCore.base.exp:
    * WebCore.xcodeproj/project.pbxproj:
    * bridge/c/c_instance.cpp:
    (JSC::Bindings::CRuntimeMethod::CRuntimeMethod):new class to distinguish this type of RuntimeMethod.
    (JSC::Bindings::CInstance::getMethod): create an appropriate sublclass of RuntimeMethod.
    (JSC::Bindings::CInstance::invokeMethod): dynamically check the type of the RuntimeMethod.
    * bridge/c/c_instance.h:
    * bridge/jni/jsc/JavaInstanceJSC.cpp:
    (JavaRuntimeMethod::JavaRuntimeMethod): new class to distinguish this type of RuntimeMethod.
    (JavaInstance::getMethod): create an appropriate sublclass of RuntimeMethod.
    (JavaInstance::invokeMethod): dynamically check the type of the RuntimeMethod.
    * bridge/jni/jsc/JavaInstanceJSC.h:
    * bridge/jsc/BridgeJSC.h:
    * bridge/objc/objc_instance.h:
    * bridge/objc/objc_instance.mm:
    (ObjcRuntimeMethod::ObjcRuntimeMethod): new class to distinguish this type of RuntimeMethod.
    (ObjcInstance::getMethod): create an appropriate sublclass of RuntimeMethod.
    (ObjcInstance::invokeMethod): dynamically check the type of the RuntimeMethod.
    (ObjcInstance::invokeObjcMethod): new method, takes an ObjcMethod* as an argument so that we don't need to dynamically determine the type.
    * bridge/objc/objc_runtime.mm:
    (JSC::Bindings::callObjCFallbackObject): use new invokeObjcMethod method.
    * bridge/runtime_method.cpp:
    (JSC::callRuntimeMethod): pass RuntimeMethod as argument to invokeMethod, rather than its MethodList.
    * bridge/runtime_object.cpp:
    (JSC::RuntimeObject::methodGetter): use new getMethod method.
    
    WebKit/mac:
    
    * Plugins/Hosted/ProxyInstance.h:
    * Plugins/Hosted/ProxyInstance.mm:
    (WebKit::PluginRuntimeMethod::PluginRuntimeMethod): new class to distinguish this type of RuntimeMethod.
    (WebKit::ProxyInstance::getMethod): create an appropriate sublclass of RuntimeMethod.
    (WebKit::ProxyInstance::invokeMethod): dynamically check the type of the RuntimeMethod.
    
    LayoutTests:
    
    * java/java-and-plugins.html: Add tests for passing mismatched this objects to methdods.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55312 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 7e27bc4..e84c691 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2010-02-26  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Bug 35401 - Fix handling of errors in handling calls over bridge,
+        where base object bridge-type does not match method bridge-type.
+
+        The code assumes users will only attempt to invoke a Java method
+        on a Java base object, etc.
+        Add language specific subclasses of RuntimeMethod, and pass the
+        RuntimeMethod into invokeMethod, so we can typecheck before
+        casting.  Throw an exception on type mismatch.
+
+        * java/java-and-plugins.html: Add tests for passing mismatched this objects to methdods.
+
 2010-02-26  Alex Milowski  <alex at milowski.com>
 
         Reviewed by Kenneth Rohde Christiansen.
diff --git a/LayoutTests/java/java-and-plugins-expected.txt b/LayoutTests/java/java-and-plugins-expected.txt
index 0d30eb0..6882241 100644
--- a/LayoutTests/java/java-and-plugins-expected.txt
+++ b/LayoutTests/java/java-and-plugins-expected.txt
@@ -10,6 +10,8 @@ PASS document.plg.testHasMethod(document.javaTest.getSelf(), "getSelf") is true
 PASS document.plg.testHasMethod(document.javaTest.getSelf(), "doesNotExist") is false
 PASS document.javaTest.getAndForgetRememberedObject().objectPointer is document.plg.testObject.objectPointer
 PASS typeof document.javaTest.testGetMember(document.plg, "testDOMAccess") is "function"
+PASS tryCall(document.javaTest.getSelf, plg.testObject) is "TypeError: Attempt to invoke non-plug-in method on plug-in object."
+PASS tryCall(plg.testObject.throwException, document.javaTest) is "TypeError: Attempt to invoke non-Java method on Java object."
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/java/java-and-plugins.html b/LayoutTests/java/java-and-plugins.html
index 55bea0d..e60a3cf 100644
--- a/LayoutTests/java/java-and-plugins.html
+++ b/LayoutTests/java/java-and-plugins.html
@@ -34,6 +34,21 @@ shouldBe('document.javaTest.getAndForgetRememberedObject().objectPointer', 'docu
 
 shouldBe('typeof document.javaTest.testGetMember(document.plg, "testDOMAccess")', '"function"');
 
+// Try calling a plug-in method with a Java object as this, and vice versa.
+// These should throw an exception.
+function tryCall(func, thisObj)
+{
+    var exception = "NO EXCEPTION";
+    try {
+        func.call(thisObj);
+    } catch (e) {
+        exception = e;
+    }
+    return String(exception);
+}
+shouldBe('tryCall(document.javaTest.getSelf, plg.testObject)', '"TypeError: Attempt to invoke non-plug-in method on plug-in object."');
+shouldBe('tryCall(plg.testObject.throwException, document.javaTest)', '"TypeError: Attempt to invoke non-Java method on Java object."');
+
 successfullyParsed = true;
 </script>
 <script src="../fast/js/resources/js-test-post.js"></script>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 137a0e6..f0c9cba 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,42 @@
+2010-02-26  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Bug 35401 - Fix handling of errors in handling calls over bridge,
+        where base object bridge-type does not match method bridge-type.
+
+        The code assumes users will only attempt to invoke a Java method
+        on a Java base object, etc.
+        Add language specific subclasses of RuntimeMethod, and pass the
+        RuntimeMethod into invokeMethod, so we can typecheck before
+        casting.  Throw an exception on type mismatch.
+
+        * WebCore.base.exp:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bridge/c/c_instance.cpp:
+        (JSC::Bindings::CRuntimeMethod::CRuntimeMethod):new class to distinguish this type of RuntimeMethod.
+        (JSC::Bindings::CInstance::getMethod): create an appropriate sublclass of RuntimeMethod.
+        (JSC::Bindings::CInstance::invokeMethod): dynamically check the type of the RuntimeMethod.
+        * bridge/c/c_instance.h:
+        * bridge/jni/jsc/JavaInstanceJSC.cpp:
+        (JavaRuntimeMethod::JavaRuntimeMethod): new class to distinguish this type of RuntimeMethod.
+        (JavaInstance::getMethod): create an appropriate sublclass of RuntimeMethod.
+        (JavaInstance::invokeMethod): dynamically check the type of the RuntimeMethod.
+        * bridge/jni/jsc/JavaInstanceJSC.h:
+        * bridge/jsc/BridgeJSC.h:
+        * bridge/objc/objc_instance.h:
+        * bridge/objc/objc_instance.mm:
+        (ObjcRuntimeMethod::ObjcRuntimeMethod): new class to distinguish this type of RuntimeMethod.
+        (ObjcInstance::getMethod): create an appropriate sublclass of RuntimeMethod.
+        (ObjcInstance::invokeMethod): dynamically check the type of the RuntimeMethod.
+        (ObjcInstance::invokeObjcMethod): new method, takes an ObjcMethod* as an argument so that we don't need to dynamically determine the type.
+        * bridge/objc/objc_runtime.mm:
+        (JSC::Bindings::callObjCFallbackObject): use new invokeObjcMethod method.
+        * bridge/runtime_method.cpp:
+        (JSC::callRuntimeMethod): pass RuntimeMethod as argument to invokeMethod, rather than its MethodList.
+        * bridge/runtime_object.cpp:
+        (JSC::RuntimeObject::methodGetter): use new getMethod method.
+
 2010-02-26  Oliver Hunt  <oliver at apple.com>
 
         Reviewed by Geoff Garen.
diff --git a/WebCore/WebCore.PluginHostProcess.exp b/WebCore/WebCore.PluginHostProcess.exp
index ae95867..e3dd40d 100644
--- a/WebCore/WebCore.PluginHostProcess.exp
+++ b/WebCore/WebCore.PluginHostProcess.exp
@@ -1,5 +1,11 @@
 # This file gets appended to WebCore.exp when USE(PLUGIN_HOST_PROCESS) is 1.
 
+__ZN3JSC13RuntimeMethod11getCallDataERNS_8CallDataE
+__ZN3JSC13RuntimeMethod18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC13RuntimeMethod24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC13RuntimeMethod6s_infoE
+__ZN3JSC13RuntimeMethodC1EPNS_9ExecStateERKNS_10IdentifierERN3WTF6VectorIPNS_8Bindings6MethodELm0EEE
+__ZN3JSC13RuntimeMethodC2EPNS_9ExecStateERKNS_10IdentifierERN3WTF6VectorIPNS_8Bindings6MethodELm0EEE
 __ZN3JSC8Bindings10RootObjectD1Ev
 __ZN3JSC8Bindings13RuntimeObject11getCallDataERNS_8CallDataE
 __ZN3JSC8Bindings13RuntimeObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
@@ -23,3 +29,4 @@ __ZN7WebCore16ScriptController24jsObjectForPluginElementEPNS_17HTMLPlugInElement
 __ZN7WebCore6String26fromUTF8WithLatin1FallbackEPKcm
 __ZN7WebCore6String8fromUTF8EPKcm
 __ZNK3JSC8Bindings13RuntimeObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZTVN3JSC13RuntimeMethodE
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 1101930..d70e6d6 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -337,7 +337,7 @@
 		1A569D1E0D7E2B82007C3983 /* runtime_array.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A569CEF0D7E2B82007C3983 /* runtime_array.cpp */; };
 		1A569D1F0D7E2B82007C3983 /* runtime_array.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CF00D7E2B82007C3983 /* runtime_array.h */; };
 		1A569D200D7E2B82007C3983 /* runtime_method.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A569CF10D7E2B82007C3983 /* runtime_method.cpp */; };
-		1A569D210D7E2B82007C3983 /* runtime_method.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CF20D7E2B82007C3983 /* runtime_method.h */; };
+		1A569D210D7E2B82007C3983 /* runtime_method.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CF20D7E2B82007C3983 /* runtime_method.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1A569D220D7E2B82007C3983 /* runtime_object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A569CF30D7E2B82007C3983 /* runtime_object.cpp */; };
 		1A569D230D7E2B82007C3983 /* runtime_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CF40D7E2B82007C3983 /* runtime_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1A569D240D7E2B82007C3983 /* runtime_root.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A569CF50D7E2B82007C3983 /* runtime_root.cpp */; };
diff --git a/WebCore/bridge/c/c_instance.cpp b/WebCore/bridge/c/c_instance.cpp
index bb9b2ee..2adb322 100644
--- a/WebCore/bridge/c/c_instance.cpp
+++ b/WebCore/bridge/c/c_instance.cpp
@@ -35,6 +35,7 @@
 #include "c_runtime.h"
 #include "c_utility.h"
 #include "npruntime_impl.h"
+#include "runtime_method.h"
 #include "runtime_root.h"
 #include <interpreter/CallFrame.h>
 #include <runtime/ArgList.h>
@@ -107,8 +108,33 @@ bool CInstance::supportsInvokeDefaultMethod() const
     return _object->_class->invokeDefault;
 }
 
-JSValue CInstance::invokeMethod(ExecState* exec, const MethodList& methodList, const ArgList& args)
+class CRuntimeMethod : public RuntimeMethod {
+public:
+    CRuntimeMethod(ExecState* exec, const Identifier& name, Bindings::MethodList& list)
+        : RuntimeMethod(exec, name, list)
+    {
+    }
+
+    virtual const ClassInfo* classInfo() const { return &s_info; }
+
+    static const ClassInfo s_info;
+};
+
+const ClassInfo CRuntimeMethod::s_info = { "CRuntimeMethod", &RuntimeMethod::s_info, 0, 0 };
+
+JSValue CInstance::getMethod(ExecState* exec, const Identifier& propertyName)
 {
+    MethodList methodList = getClass()->methodsNamed(propertyName, this);
+    return new (exec) CRuntimeMethod(exec, propertyName, methodList);
+}
+
+JSValue CInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod, const ArgList& args)
+{
+    if (!asObject(runtimeMethod)->inherits(&CRuntimeMethod::s_info))
+        return throwError(exec, TypeError, "Attempt to invoke non-plug-in method on plug-in object.");
+
+    const MethodList& methodList = *runtimeMethod->methods();
+
     // Overloading methods are not allowed by NPObjects.  Should only be one
     // name match for a particular method.
     ASSERT(methodList.size() == 1);
diff --git a/WebCore/bridge/c/c_instance.h b/WebCore/bridge/c/c_instance.h
index b1ad6e7..be4a4cb 100644
--- a/WebCore/bridge/c/c_instance.h
+++ b/WebCore/bridge/c/c_instance.h
@@ -59,7 +59,8 @@ public:
     virtual JSValue valueOf(ExecState*) const;
     virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
 
-    virtual JSValue invokeMethod(ExecState*, const MethodList&, const ArgList&);
+    virtual JSValue getMethod(ExecState* exec, const Identifier& propertyName);
+    virtual JSValue invokeMethod(ExecState*, RuntimeMethod* method, const ArgList&);
     virtual bool supportsInvokeDefaultMethod() const;
     virtual JSValue invokeDefaultMethod(ExecState*, const ArgList&);
 
diff --git a/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp b/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
index ade26bb..585b315 100644
--- a/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
+++ b/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
@@ -34,6 +34,7 @@
 #include "JNIUtilityPrivate.h"
 #include "JavaClassJSC.h"
 #include "Logging.h"
+#include "runtime_method.h"
 #include "runtime_object.h"
 #include "runtime_root.h"
 #include <runtime/ArgList.h>
@@ -109,8 +110,33 @@ JSValue JavaInstance::booleanValue() const
     return jsBoolean(booleanValue);
 }
 
-JSValue JavaInstance::invokeMethod(ExecState* exec, const MethodList& methodList, const ArgList &args)
+class JavaRuntimeMethod : public RuntimeMethod {
+public:
+    JavaRuntimeMethod(ExecState* exec, const Identifier& name, Bindings::MethodList& list)
+        : RuntimeMethod(exec, name, list)
+    {
+    }
+
+    virtual const ClassInfo* classInfo() const { return &s_info; }
+
+    static const ClassInfo s_info;
+};
+
+const ClassInfo JavaRuntimeMethod::s_info = { "JavaRuntimeMethod", &RuntimeMethod::s_info, 0, 0 };
+
+JSValue JavaInstance::getMethod(ExecState* exec, const Identifier& propertyName)
 {
+    MethodList methodList = getClass()->methodsNamed(propertyName, this);
+    return new (exec) JavaRuntimeMethod(exec, propertyName, methodList);
+}
+
+JSValue JavaInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod, const ArgList &args)
+{
+    if (!asObject(runtimeMethod)->inherits(&JavaRuntimeMethod::s_info))
+        return throwError(exec, TypeError, "Attempt to invoke non-Java method on Java object.");
+
+    const MethodList& methodList = *runtimeMethod->methods();
+
     int i;
     int count = args.size();
     JSValue resultValue;
diff --git a/WebCore/bridge/jni/jsc/JavaInstanceJSC.h b/WebCore/bridge/jni/jsc/JavaInstanceJSC.h
index 4bebdff..d395cc8 100644
--- a/WebCore/bridge/jni/jsc/JavaInstanceJSC.h
+++ b/WebCore/bridge/jni/jsc/JavaInstanceJSC.h
@@ -82,7 +82,8 @@ public:
     virtual JSValue valueOf(ExecState*) const;
     virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
 
-    virtual JSValue invokeMethod(ExecState* exec, const MethodList& method, const ArgList& args);
+    virtual JSValue getMethod(ExecState* exec, const Identifier& propertyName);
+    virtual JSValue invokeMethod(ExecState* exec, RuntimeMethod* method, const ArgList& args);
 
     jobject javaInstance() const { return m_instance->m_instance; }
 
diff --git a/WebCore/bridge/jsc/BridgeJSC.h b/WebCore/bridge/jsc/BridgeJSC.h
index 423abd2..8379170 100644
--- a/WebCore/bridge/jsc/BridgeJSC.h
+++ b/WebCore/bridge/jsc/BridgeJSC.h
@@ -40,6 +40,7 @@ class ArgList;
 class Identifier;
 class JSGlobalObject;
 class PropertyNameArray;
+class RuntimeMethod;
 
 namespace Bindings {
 
@@ -90,7 +91,8 @@ public:
     // Returns false if the value was not set successfully.
     virtual bool setValueOfUndefinedField(ExecState*, const Identifier&, JSValue) { return false; }
 
-    virtual JSValue invokeMethod(ExecState*, const MethodList&, const ArgList& args) = 0;
+    virtual JSValue getMethod(ExecState* exec, const Identifier& propertyName) = 0;
+    virtual JSValue invokeMethod(ExecState*, RuntimeMethod* method, const ArgList& args) = 0;
 
     virtual bool supportsInvokeDefaultMethod() const { return false; }
     virtual JSValue invokeDefaultMethod(ExecState*, const ArgList&) { return jsUndefined(); }
diff --git a/WebCore/bridge/objc/objc_instance.h b/WebCore/bridge/objc/objc_instance.h
index e1f73c3..7e87188 100644
--- a/WebCore/bridge/objc/objc_instance.h
+++ b/WebCore/bridge/objc/objc_instance.h
@@ -46,8 +46,10 @@ public:
         
     virtual JSValue valueOf(ExecState*) const;
     virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
-    
-    virtual JSValue invokeMethod(ExecState*, const MethodList&, const ArgList&);
+
+    virtual JSValue getMethod(ExecState* exec, const Identifier& propertyName);
+    JSValue invokeObjcMethod(ExecState*, ObjcMethod* method, const ArgList&);
+    virtual JSValue invokeMethod(ExecState*, RuntimeMethod* method, const ArgList&);
     virtual bool supportsInvokeDefaultMethod() const;
     virtual JSValue invokeDefaultMethod(ExecState*, const ArgList&);
 
diff --git a/WebCore/bridge/objc/objc_instance.mm b/WebCore/bridge/objc/objc_instance.mm
index 314658c..c06c649 100644
--- a/WebCore/bridge/objc/objc_instance.mm
+++ b/WebCore/bridge/objc/objc_instance.mm
@@ -26,6 +26,7 @@
 #import "config.h"
 #import "objc_instance.h"
 
+#import "runtime_method.h"
 #import "FoundationExtras.h"
 #import "ObjCRuntimeObject.h"
 #import "WebScriptObject.h"
@@ -173,7 +174,41 @@ bool ObjcInstance::supportsInvokeDefaultMethod() const
     return [_instance.get() respondsToSelector:@selector(invokeDefaultMethodWithArguments:)];
 }
 
-JSValue ObjcInstance::invokeMethod(ExecState* exec, const MethodList &methodList, const ArgList &args)
+class ObjCRuntimeMethod : public RuntimeMethod {
+public:
+    ObjCRuntimeMethod(ExecState* exec, const Identifier& name, Bindings::MethodList& list)
+        : RuntimeMethod(exec, name, list)
+    {
+    }
+
+    virtual const ClassInfo* classInfo() const { return &s_info; }
+
+    static const ClassInfo s_info;
+};
+
+const ClassInfo ObjCRuntimeMethod::s_info = { "ObjCRuntimeMethod", &RuntimeMethod::s_info, 0, 0 };
+
+JSValue ObjcInstance::getMethod(ExecState* exec, const Identifier& propertyName)
+{
+    MethodList methodList = getClass()->methodsNamed(propertyName, this);
+    return new (exec) ObjCRuntimeMethod(exec, propertyName, methodList);
+}
+
+JSValue ObjcInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod, const ArgList &args)
+{
+    if (!asObject(runtimeMethod)->inherits(&ObjCRuntimeMethod::s_info))
+        return throwError(exec, TypeError, "Attempt to invoke non-plug-in method on plug-in object.");
+
+    const MethodList& methodList = *runtimeMethod->methods();
+
+    // Overloading methods is not allowed in ObjectiveC.  Should only be one
+    // name match for a particular method.
+    ASSERT(methodList.size() == 1);
+
+    return invokeObjcMethod(exec, static_cast<ObjcMethod*>(methodList[0]), args);
+}
+
+JSValue ObjcInstance::invokeObjcMethod(ExecState* exec, ObjcMethod* method, const ArgList &args)
 {
     JSValue result = jsUndefined();
     
@@ -181,13 +216,7 @@ JSValue ObjcInstance::invokeMethod(ExecState* exec, const MethodList &methodList
 
     setGlobalException(nil);
     
-    // Overloading methods is not allowed in ObjectiveC.  Should only be one
-    // name match for a particular method.
-    ASSERT(methodList.size() == 1);
-
 @try {
-    ObjcMethod* method = 0;
-    method = static_cast<ObjcMethod*>(methodList[0]);
     NSMethodSignature* signature = method->getMethodSignature();
     NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
     [invocation setSelector:method->selector()];
diff --git a/WebCore/bridge/objc/objc_runtime.mm b/WebCore/bridge/objc/objc_runtime.mm
index 652f4d1..f845a00 100644
--- a/WebCore/bridge/objc/objc_runtime.mm
+++ b/WebCore/bridge/objc/objc_runtime.mm
@@ -238,9 +238,7 @@ static JSValue JSC_HOST_CALL callObjCFallbackObject(ExecState* exec, JSObject* f
         const Identifier& nameIdentifier = static_cast<ObjcFallbackObjectImp*>(function)->propertyName();
         RetainPtr<CFStringRef> name(AdoptCF, CFStringCreateWithCharacters(0, nameIdentifier.data(), nameIdentifier.size()));
         fallbackMethod->setJavaScriptName(name.get());
-        MethodList methodList;
-        methodList.append(fallbackMethod.get());
-        result = objcInstance->invokeMethod(exec, methodList, args);
+        result = objcInstance->invokeObjcMethod(exec, fallbackMethod.get(), args);
     }
             
     objcInstance->end();
diff --git a/WebCore/bridge/qt/qt_instance.cpp b/WebCore/bridge/qt/qt_instance.cpp
index 8822c72..3df6a89 100644
--- a/WebCore/bridge/qt/qt_instance.cpp
+++ b/WebCore/bridge/qt/qt_instance.cpp
@@ -234,13 +234,18 @@ void QtInstance::getPropertyNames(ExecState* exec, PropertyNameArray& array)
     }
 }
 
-JSValue QtInstance::invokeMethod(ExecState*, const MethodList&, const ArgList&)
+JSValue QtInstance::getMethod(ExecState* exec, const Identifier& propertyName)
+{
+    MethodList methodList = getClass()->methodsNamed(propertyName, this);
+    return new (exec) RuntimeMethod(exec, propertyName, methodList);
+}
+
+JSValue QtInstance::invokeMethod(ExecState*, RuntimeMethod*, const ArgList&)
 {
     // Implemented via fallbackMethod & QtRuntimeMetaMethod::callAsFunction
     return jsUndefined();
 }
 
-
 JSValue QtInstance::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
     if (hint == PreferString)
diff --git a/WebCore/bridge/qt/qt_instance.h b/WebCore/bridge/qt/qt_instance.h
index 3a938a3..607f133 100644
--- a/WebCore/bridge/qt/qt_instance.h
+++ b/WebCore/bridge/qt/qt_instance.h
@@ -50,7 +50,8 @@ public:
 
     void markAggregate(MarkStack&);
 
-    virtual JSValue invokeMethod(ExecState*, const MethodList&, const ArgList&);
+    virtual JSValue getMethod(ExecState* exec, const Identifier& propertyName);
+    virtual JSValue invokeMethod(ExecState*, RuntimeMethod*, const ArgList&);
 
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
diff --git a/WebCore/bridge/qt/qt_pixmapruntime.cpp b/WebCore/bridge/qt/qt_pixmapruntime.cpp
index 4ef472c..10de10a 100644
--- a/WebCore/bridge/qt/qt_pixmapruntime.cpp
+++ b/WebCore/bridge/qt/qt_pixmapruntime.cpp
@@ -33,6 +33,7 @@
 #include <QVariant>
 #include <runtime_object.h>
 #include <runtime_root.h>
+#include <runtime_method.h>
 
 using namespace WebCore;
 namespace JSC {
@@ -177,8 +178,16 @@ Class* QtPixmapInstance::getClass() const
     return &qt_pixmap_metaData.cls;
 }
 
-JSValue QtPixmapInstance::invokeMethod(ExecState* exec, const MethodList& methods, const ArgList& args)
+JSValue QtPixmapInstance::getMethod(ExecState* exec, const Identifier& propertyName)
 {
+    MethodList methodList = getClass()->methodsNamed(propertyName, this);
+    return new (exec) RuntimeMethod(exec, propertyName, methodList);
+}
+
+JSValue QtPixmapInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod, const ArgList& args)
+{
+    const MethodList& methodList = *runtimeMethod->methods();
+
     if (methods.size() == 1) {
         QtPixmapRuntimeMethod* method = static_cast<QtPixmapRuntimeMethod*>(methods[0]);
         return method->invoke(exec, this, args);
diff --git a/WebCore/bridge/qt/qt_pixmapruntime.h b/WebCore/bridge/qt/qt_pixmapruntime.h
index 5455298..a0e0e26 100644
--- a/WebCore/bridge/qt/qt_pixmapruntime.h
+++ b/WebCore/bridge/qt/qt_pixmapruntime.h
@@ -32,7 +32,8 @@ class QtPixmapInstance : public Instance {
 public:
     QtPixmapInstance(PassRefPtr<RootObject> rootObj, const QVariant& newData);
     virtual Class* getClass() const;
-    virtual JSValue invokeMethod(ExecState*, const MethodList&, const ArgList& args);
+    virtual JSValue getMethod(ExecState* exec, const Identifier& propertyName);
+    virtual JSValue invokeMethod(ExecState*, RuntimeMethod*, const ArgList& args);
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
     virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
diff --git a/WebCore/bridge/runtime_method.cpp b/WebCore/bridge/runtime_method.cpp
index ff1280a..2af9386 100644
--- a/WebCore/bridge/runtime_method.cpp
+++ b/WebCore/bridge/runtime_method.cpp
@@ -41,7 +41,7 @@ using namespace Bindings;
 
 ASSERT_CLASS_FITS_IN_CELL(RuntimeMethod);
 
-const ClassInfo RuntimeMethod::s_info = { "RuntimeMethod", 0, 0, 0 };
+const ClassInfo RuntimeMethod::s_info = { "RuntimeMethod", &InternalFunction::info, 0, 0 };
 
 RuntimeMethod::RuntimeMethod(ExecState* exec, const Identifier& ident, Bindings::MethodList& m)
     // FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object
@@ -113,7 +113,7 @@ static JSValue JSC_HOST_CALL callRuntimeMethod(ExecState* exec, JSObject* functi
     ASSERT(instance);
 
     instance->begin();
-    JSValue result = instance->invokeMethod(exec, *method->methods(), args);
+    JSValue result = instance->invokeMethod(exec, method, args);
     instance->end();
     return result;
 }
diff --git a/WebCore/bridge/runtime_method.h b/WebCore/bridge/runtime_method.h
index 914ab00..1a71e93 100644
--- a/WebCore/bridge/runtime_method.h
+++ b/WebCore/bridge/runtime_method.h
@@ -50,6 +50,8 @@ public:
         return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
     }
 
+    virtual const ClassInfo* classInfo() const { return &s_info; }
+
 private:
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | InternalFunction::StructureFlags;
     static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
diff --git a/WebCore/bridge/runtime_object.cpp b/WebCore/bridge/runtime_object.cpp
index 3e21a8f..ee81f2c 100644
--- a/WebCore/bridge/runtime_object.cpp
+++ b/WebCore/bridge/runtime_object.cpp
@@ -113,13 +113,11 @@ JSValue RuntimeObject::methodGetter(ExecState* exec, const Identifier& propertyN
     
     instance->begin();
 
-    Class *aClass = instance->getClass();
-    MethodList methodList = aClass->methodsNamed(propertyName, instance.get());
-    JSValue result = new (exec) RuntimeMethod(exec, propertyName, methodList);
+    JSValue method = instance->getMethod(exec, propertyName);
 
     instance->end();
             
-    return result;
+    return method;
 }
 
 bool RuntimeObject::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
diff --git a/WebKit/mac/ChangeLog b/WebKit/mac/ChangeLog
index ca25309..5a07ce0 100644
--- a/WebKit/mac/ChangeLog
+++ b/WebKit/mac/ChangeLog
@@ -1,3 +1,22 @@
+2010-02-26  Gavin Barraclough  <barraclough at apple.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Bug 35401 - Fix handling of errors in handling calls over bridge,
+        where base object bridge-type does not match method bridge-type.
+
+        The code assumes users will only attempt to invoke a Java method
+        on a Java base object, etc.
+        Add language specific subclasses of RuntimeMethod, and pass the
+        RuntimeMethod into invokeMethod, so we can typecheck before
+        casting.  Throw an exception on type mismatch.
+
+        * Plugins/Hosted/ProxyInstance.h:
+        * Plugins/Hosted/ProxyInstance.mm:
+        (WebKit::PluginRuntimeMethod::PluginRuntimeMethod): new class to distinguish this type of RuntimeMethod.
+        (WebKit::ProxyInstance::getMethod): create an appropriate sublclass of RuntimeMethod.
+        (WebKit::ProxyInstance::invokeMethod): dynamically check the type of the RuntimeMethod.
+
 2010-02-25  Alexey Proskuryakov  <ap at apple.com>
 
         Reviewed by Geoffrey Garen.
diff --git a/WebKit/mac/ForwardingHeaders/runtime/Error.h b/WebKit/mac/ForwardingHeaders/runtime/Error.h
new file mode 100644
index 0000000..05d7752
--- /dev/null
+++ b/WebKit/mac/ForwardingHeaders/runtime/Error.h
@@ -0,0 +1 @@
+#import <JavaScriptCore/Error.h>
diff --git a/WebKit/mac/Plugins/Hosted/ProxyInstance.h b/WebKit/mac/Plugins/Hosted/ProxyInstance.h
index a56f367..c8fb118 100644
--- a/WebKit/mac/Plugins/Hosted/ProxyInstance.h
+++ b/WebKit/mac/Plugins/Hosted/ProxyInstance.h
@@ -63,7 +63,8 @@ private:
 
     virtual JSC::Bindings::Class* getClass() const;
 
-    virtual JSC::JSValue invokeMethod(JSC::ExecState*, const JSC::Bindings::MethodList&, const JSC::ArgList& args);
+    virtual JSC::JSValue getMethod(JSC::ExecState* exec, const JSC::Identifier& propertyName);
+    virtual JSC::JSValue invokeMethod(JSC::ExecState*, JSC::RuntimeMethod*, const JSC::ArgList& args);
 
     virtual bool supportsInvokeDefaultMethod() const;
     virtual JSC::JSValue invokeDefaultMethod(JSC::ExecState*, const JSC::ArgList&);
diff --git a/WebKit/mac/Plugins/Hosted/ProxyInstance.mm b/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
index 961347b..f2df06f 100644
--- a/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
+++ b/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
@@ -32,6 +32,8 @@
 #import <WebCore/IdentifierRep.h>
 #import <WebCore/JSDOMWindow.h>
 #import <WebCore/npruntime_impl.h>
+#import <WebCore/runtime_method.h>
+#import <runtime/Error.h>
 #import <runtime/PropertyNameArray.h>
 
 extern "C" {
@@ -170,8 +172,33 @@ JSValue ProxyInstance::invoke(JSC::ExecState* exec, InvokeType type, uint64_t id
     return m_instanceProxy->demarshalValue(exec, (char*)CFDataGetBytePtr(reply->m_result.get()), CFDataGetLength(reply->m_result.get()));
 }
 
-JSValue ProxyInstance::invokeMethod(ExecState* exec, const MethodList& methodList, const ArgList& args)
+class ProxyRuntimeMethod : public RuntimeMethod {
+public:
+    ProxyRuntimeMethod(ExecState* exec, const Identifier& name, Bindings::MethodList& list)
+        : RuntimeMethod(exec, name, list)
+    {
+    }
+
+    virtual const ClassInfo* classInfo() const { return &s_info; }
+
+    static const ClassInfo s_info;
+};
+
+const ClassInfo ProxyRuntimeMethod::s_info = { "ProxyRuntimeMethod", &RuntimeMethod::s_info, 0, 0 };
+
+JSValue ProxyInstance::getMethod(JSC::ExecState* exec, const JSC::Identifier& propertyName)
+{
+    MethodList methodList = getClass()->methodsNamed(propertyName, this);
+    return new (exec) ProxyRuntimeMethod(exec, propertyName, methodList);
+}
+
+JSValue ProxyInstance::invokeMethod(ExecState* exec, JSC::RuntimeMethod* runtimeMethod, const ArgList& args)
 {
+    if (!asObject(runtimeMethod)->inherits(&ProxyRuntimeMethod::s_info))
+        return throwError(exec, TypeError, "Attempt to invoke non-plug-in method on plug-in object.");
+
+    const MethodList& methodList = *runtimeMethod->methods();
+
     ASSERT(methodList.size() == 1);
 
     ProxyMethod* method = static_cast<ProxyMethod*>(methodList[0]);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list