changeset 9638:ecea43f5734c

8152737: Crash in RuntimeObject::put when object passed to JSObject::setMember is GCed Reviewed-by: kcr, azvegint
author mbilla
date Mon, 28 Mar 2016 18:34:42 -0700
parents ba0ceeedd0e0
children e7d4e055e2ae
files modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaArrayJSC.cpp modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaClassJSC.cpp modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaClassJSC.h modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
diffstat 4 files changed, 38 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaArrayJSC.cpp	Thu Mar 24 10:12:08 2016 -0700
+++ b/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaArrayJSC.cpp	Mon Mar 28 18:34:42 2016 -0700
@@ -54,17 +54,20 @@
     : Array(rootObject)
 {
     m_array = JobjectWrapper::create(array);
+
+    // Java array are fixed length, so we can cache length.
+    JNIEnv* env = getJNIEnv();
+
     // Since m_array->instance() is WeakGlobalRef, creating a localref to safeguard instance() from GC
     JLObject jlarrayinstance(m_array->instance(), true);
 
     if (!jlarrayinstance) {
         LOG_ERROR("Could not get javaInstance for %p in JavaArray Constructor", jlarrayinstance);
-        return;
+        m_length = 0;
+    } else {
+        m_length = env->GetArrayLength(static_cast<jarray>(m_array->instance()));
     }
 
-    // Java array are fixed length, so we can cache length.
-    JNIEnv* env = getJNIEnv();
-    m_length = env->GetArrayLength(static_cast<jarray>(m_array->instance()));
     m_type = strdup(type);
     m_accessControlContext = JobjectWrapper::create(accessControlContext, true);
 }
--- a/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaClassJSC.cpp	Thu Mar 24 10:12:08 2016 -0700
+++ b/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaClassJSC.cpp	Mon Mar 28 18:34:42 2016 -0700
@@ -44,9 +44,13 @@
     JLObject jlinstance(anInstance, true);
 
     if (!jlinstance) {
-        LOG_ERROR("Could not get javaInstance for %p in JavaClass::JavaClass", jlinstance);
-        m_name = fastStrDup("<Unknown>");
-        return;
+        LOG_ERROR("Could not get javaInstance for %p in JavaClass Constructor", jlinstance);
+        anInstance = createDummyObject();
+        if (anInstance == NULL) {
+            LOG_ERROR("Could not createDummyObject for %p in JavaClass Constructor", anInstance);
+            m_name = fastStrDup("<Unknown>");
+            return;
+        }
     }
 
     jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
@@ -133,6 +137,29 @@
     m_methods.clear();
 }
 
+jobject JavaClass::createDummyObject()
+{
+    JNIEnv* env = getJNIEnv();
+    jclass objectCls = env->FindClass("java/lang/Object");
+    if (!objectCls) {
+        LOG_ERROR("Unable to FindClass for java/lang/Object in JavaClass::createDummyObject");
+        return NULL;
+    }
+
+    jmethodID methodId = env->GetMethodID(objectCls, "<init>", "()V");
+    if (!methodId) {
+        LOG_ERROR("Unable to Get MethodID in JavaClass::createDummyObject");
+        return NULL;
+    }
+
+    jobject instance = env->NewObject(objectCls, methodId);
+    if (!instance) {
+        LOG_ERROR("Unable to create NewObject in JavaClass::createDummyObject");
+        return NULL;
+    }
+    return instance;
+}
+
 Method *JavaClass::methodNamed(PropertyName propertyName, Instance*) const
 {
     const String name(propertyName.publicName());
--- a/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaClassJSC.h	Thu Mar 24 10:12:08 2016 -0700
+++ b/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaClassJSC.h	Mon Mar 28 18:34:42 2016 -0700
@@ -50,6 +50,7 @@
     bool isStringClass() const;
 
 private:
+    jobject createDummyObject();
     const char* m_name;
     mutable FieldMap m_fields;
     mutable MethodListMap m_methods;
--- a/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp	Thu Mar 24 10:12:08 2016 -0700
+++ b/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp	Mon Mar 28 18:34:42 2016 -0700
@@ -83,15 +83,6 @@
 
 Class* JavaInstance::getClass() const
 {
-    jobject obj = m_instance->instance();
-    // Since m_instance->instance() is WeakGlobalRef, creating a localref to safeguard instance() from GC
-    JLObject jlinstance(obj, true);
-
-    if (!jlinstance) {
-        LOG_ERROR("Could not get javaInstance for %p in JavaInstance::getClass", jlinstance);
-        return NULL;
-    }
-
     if (!m_class) {
         jobject acc  = accessControlContext();
         m_class = new JavaClass (m_instance->instance(), rootObject(), acc);