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
+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:
// 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.
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;
}
#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;
{
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);
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;
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;
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:
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
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");
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);
}
// 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
Bindings::Array *getConcreteArray() const { return _array; }
-private:
static const ClassInfo info;
+
+private:
Bindings::Array *_array;
};