Fixed <rdar://problem/3853676> Browser Crash when accessing CCWeb Progress Page...
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Jan 2005 01:39:19 +0000 (01:39 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Jan 2005 01:39:19 +0000 (01:39 +0000)
Fixed the following problems with LiveConnect that are demonstrated by the application
described in 3853676.

1.  If a nil object is passed in an array from Java to JavaScript we will crash.
2.  We sometimes will incorrectly attempt to access a generic JavaScript as a Java runtime object wrapper.
3.  We will sometimes fail to find the correct static method ID.

        Reviewed by Maciej.

        * bindings/jni/jni_jsobject.cpp:
        (JSObject::convertJObjectToValue):
        (JSObject::listFromJArray):
        * bindings/jni/jni_runtime.cpp:
        (JavaField::valueFromInstance):
        (JavaField::setValueToInstance):
        * bindings/jni/jni_utility.cpp:
        (KJS::Bindings::getMethodID):
        (KJS::Bindings::convertValueToJValue):
        * bindings/runtime_array.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@8408 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/bindings/jni/jni_jsobject.cpp
JavaScriptCore/bindings/jni/jni_runtime.cpp
JavaScriptCore/bindings/jni/jni_utility.cpp
JavaScriptCore/bindings/runtime_array.h

index c877f168355898ebcc93aab73c9cccdfc438c7bb..6ff8b7cf077e93e1dcbe0a51cb058615a16d7654 100644 (file)
@@ -1,3 +1,27 @@
+2005-01-19  Richard Williamson   <rjw@apple.com>
+
+       Fixed <rdar://problem/3853676> Browser Crash when accessing CCWeb Progress Page - KJS::Bindings::convertValueToJValue
+
+       Fixed the following problems with LiveConnect that are demonstrated by the application
+       described in 3853676.
+
+       1.  If a nil object is passed in an array from Java to JavaScript we will crash.
+       2.  We sometimes will incorrectly attempt to access a generic JavaScript as a Java runtime object wrapper.
+       3.  We will sometimes fail to find the correct static method ID.
+
+        Reviewed by Maciej.
+
+        * bindings/jni/jni_jsobject.cpp:
+        (JSObject::convertJObjectToValue):
+        (JSObject::listFromJArray):
+        * bindings/jni/jni_runtime.cpp:
+        (JavaField::valueFromInstance):
+        (JavaField::setValueToInstance):
+        * bindings/jni/jni_utility.cpp:
+        (KJS::Bindings::getMethodID):
+        (KJS::Bindings::convertValueToJValue):
+        * bindings/runtime_array.h:
+
 2005-01-18  Richard Williamson   <rjw@apple.com>
 
        Fixed several issues all arising from analysis of plugin detection code at ifilm.com:
index 95c0f914888da7ec0133b0f1f690ca5a8b52f430..0f862832150b3aab523ad3b981eb3f3c9bfc3503 100644 (file)
@@ -420,9 +420,7 @@ KJS::Value JSObject::convertJObjectToValue (jobject theObject) const
     // figure 22-4.
     jobject classOfInstance = callJNIObjectMethod(theObject, "getClass", "()Ljava/lang/Class;");
     jstring className = (jstring)callJNIObjectMethod(classOfInstance, "getName", "()Ljava/lang/String;");
-    
-    JS_LOG ("converting instance of class %s\n", Bindings::JavaString(className).UTF8String());
-    
+        
     if (strcmp(Bindings::JavaString(className).UTF8String(), "netscape.javascript.JSObject") == 0) {
         // Pull the nativeJSObject value from the Java instance.  This is a
         // pointer to the ObjectImp.
@@ -454,8 +452,14 @@ KJS::List JSObject::listFromJArray(jobjectArray jArray) const
     
     for (i = 0; i < numObjects; i++) {
         jobject anObject = env->GetObjectArrayElement ((jobjectArray)jArray, i);
-        aList.append (convertJObjectToValue(anObject));
-        env->DeleteLocalRef (anObject);
+       if (anObject) {
+           aList.append (convertJObjectToValue(anObject));
+           env->DeleteLocalRef (anObject);
+       }
+       else {
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+       }
     }
     return aList;
 }
index c49f10360b1b53ba78c9f5e18ba24c05f0790365..9db8c452a8a49e546999b93f3dc4e1f20ca92a5a 100644 (file)
 #include <runtime_object.h>
 #include <runtime_root.h>
 
+#ifdef NDEBUG
+#define JS_LOG(formatAndArgs...) ((void)0)
+#else
+#define JS_LOG(formatAndArgs...) { \
+    fprintf (stderr, "%s:%d -- %s:  ", __FILE__, __LINE__, __FUNCTION__); \
+    fprintf(stderr, formatAndArgs); \
+}
+#endif
+
 using namespace KJS;
 using namespace KJS::Bindings;
 
@@ -100,6 +109,8 @@ KJS::Value JavaField::valueFromInstance(KJS::ExecState *exec, const Instance *i)
 {
     const JavaInstance *instance = static_cast<const JavaInstance *>(i);
 
+    Value jsresult = Undefined();
+    
     switch (_JNIType) {
         case object_type: {
            jvalue result = dispatchValueFromInstance (exec, instance, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", object_type);
@@ -107,10 +118,10 @@ KJS::Value JavaField::valueFromInstance(KJS::ExecState *exec, const Instance *i)
 
             const char *arrayType = type();
             if (arrayType[0] == '[') {
-                return JavaArray::convertJObjectToArray (exec, anObject, arrayType, instance->executionContext());
+                jsresult = JavaArray::convertJObjectToArray (exec, anObject, arrayType, instance->executionContext());
             }
             else {
-                return KJS::Object(new RuntimeObjectImp(new JavaInstance ((jobject)anObject, instance->executionContext())));
+                jsresult = KJS::Object(new RuntimeObjectImp(new JavaInstance ((jobject)anObject, instance->executionContext())));
             }
         }
         break;
@@ -118,7 +129,7 @@ KJS::Value JavaField::valueFromInstance(KJS::ExecState *exec, const Instance *i)
         case boolean_type: {
            jvalue result = dispatchValueFromInstance (exec, instance, "getBoolean", "(Ljava/lang/Object;)Z", boolean_type);
            jboolean value = result.z;
-            return KJS::Boolean((bool)value);
+            jsresult = KJS::Boolean((bool)value);
         }
         break;
             
@@ -126,11 +137,13 @@ KJS::Value JavaField::valueFromInstance(KJS::ExecState *exec, const Instance *i)
         case char_type:
         case short_type:
         
-        case int_type:
+        case int_type: {
             jint value;
            jvalue result = dispatchValueFromInstance (exec, instance, "getInt", "(Ljava/lang/Object;)I", int_type);
            value = result.i;
-            return Number((int)value);
+            jsresult = Number((int)value);
+       }
+       break;
 
         case long_type:
         case float_type:
@@ -138,13 +151,16 @@ KJS::Value JavaField::valueFromInstance(KJS::ExecState *exec, const Instance *i)
             jdouble value;
            jvalue result = dispatchValueFromInstance (exec, instance, "getDouble", "(Ljava/lang/Object;)D", double_type);
            value = result.i;
-            return Number((double)value);
+            jsresult = Number((double)value);
         }
         break;
         default:
         break;
     }
-    return Undefined();
+
+    JS_LOG ("getting %s = %s\n", name(), jsresult.toString(exec).ascii());
+    
+    return jsresult;
 }
 
 void JavaField::dispatchSetValueToInstance(KJS::ExecState *exec, const JavaInstance *instance, jvalue javaValue, const char *name, const char *sig) const
@@ -181,6 +197,8 @@ void JavaField::setValueToInstance(KJS::ExecState *exec, const Instance *i, cons
     const JavaInstance *instance = static_cast<const JavaInstance *>(i);
     jvalue javaValue = convertValueToJValue (exec, aValue, _JNIType, type());
 
+    JS_LOG ("setting value %s to %s\n", name(), aValue.toString(exec).ascii());
+
     switch (_JNIType) {
         case object_type: {
            dispatchSetValueToInstance (exec, instance, javaValue, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V");
index 53eaf0b89ff2e64beb6a52185fb9b14d6c4daa42..314c8ee683ec71dc1f0a89cc68d4deb62987e2e2 100644 (file)
@@ -279,6 +279,13 @@ jmethodID KJS::Bindings::getMethodID (jobject obj, const char *name, const char
     jclass cls = env->GetObjectClass(obj);
     if ( cls != NULL ) {
             mid = env->GetMethodID(cls, name, sig);
+           if (!mid) {
+                env->ExceptionClear();
+               mid = env->GetStaticMethodID(cls, name, sig);
+               if (!mid) {
+                   env->ExceptionClear();
+               }
+           }
         }
         env->DeleteLocalRef(cls);
     }
@@ -710,16 +717,16 @@ jvalue KJS::Bindings::convertValueToJValue (KJS::ExecState *exec, KJS::Value val
             // First see if we have a Java instance.
             if (value.type() == KJS::ObjectType){
                 KJS::ObjectImp *objectImp = static_cast<KJS::ObjectImp*>(value.imp());
-                if (strcmp(objectImp->classInfo()->className, "RuntimeObject") == 0) {
-                    KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(value.imp());
-                    JavaInstance *instance = static_cast<JavaInstance*>(imp->getInternalInstance());
-                    result.l = instance->javaInstance();
-                }
-                else if (strcmp(objectImp->classInfo()->className, "RuntimeArray") == 0) {
-                    KJS::RuntimeArrayImp *imp = static_cast<KJS::RuntimeArrayImp *>(value.imp());
-                    JavaArray *array = static_cast<JavaArray*>(imp->getConcreteArray());
-                    result.l = array->javaArray();
-                }
+               if (objectImp->classInfo() == &KJS::RuntimeObjectImp::info) {
+                   KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(value.imp());
+                   JavaInstance *instance = static_cast<JavaInstance*>(imp->getInternalInstance());
+                   result.l = instance->javaInstance();
+               }
+               else if (objectImp->classInfo() == &KJS::RuntimeArrayImp::info) {
+                   KJS::RuntimeArrayImp *imp = static_cast<KJS::RuntimeArrayImp *>(value.imp());
+                   JavaArray *array = static_cast<JavaArray*>(imp->getConcreteArray());
+                   result.l = array->javaArray();
+               }
             }
             
             // Now convert value to a string if the target type is a java.lang.string, and we're not
index e05ee217c5b6705197c79acfbe28b1294dd4fde3..9f7f79adfd25c25a9db0f34dbc87cf511a8cc649 100644 (file)
@@ -53,8 +53,9 @@ public:
     
     Bindings::Array *getConcreteArray() const { return _array; }
 
-private:
     static const ClassInfo info;
+
+private:
     Bindings::Array *_array;
 };