summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
authorSelim Gurun <sgurun@google.com>2012-09-10 18:16:02 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-09-10 18:16:02 -0700
commita3bef91fa82b756b62aceb8ee1fa431fbad8f649 (patch)
tree2db298a6908f27f9ff25794a324aff43a5c2c83c /Source/WebCore
parent5248b7b4129bb49b803aee8bfec7ef35171e1325 (diff)
parentf2d8c5bed31609d7d6e3ae77f33e90ea7f888eb3 (diff)
downloadexternal_webkit-a3bef91fa82b756b62aceb8ee1fa431fbad8f649.zip
external_webkit-a3bef91fa82b756b62aceb8ee1fa431fbad8f649.tar.gz
external_webkit-a3bef91fa82b756b62aceb8ee1fa431fbad8f649.tar.bz2
Merge "Control access to inherited methods of jsinterface objects" into jb-mr1-dev
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp10
-rw-r--r--Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h4
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp74
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h16
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp17
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h8
6 files changed, 120 insertions, 9 deletions
diff --git a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
index 15b4bda..c6e0a6c 100644
--- a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
+++ b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.cpp
@@ -206,7 +206,7 @@ JavaValue convertNPVariantToJavaValue(NPVariant value, const String& javaClass)
break;
}
- result.m_objectValue = adoptRef(new JavaInstanceJobject(javaArray));
+ result.m_objectValue = adoptRef(new JavaInstanceJobject(javaArray, false));
env->DeleteLocalRef(javaArray);
}
break;
@@ -421,7 +421,11 @@ void convertJavaValueToNPVariant(JavaValue value, NPVariant* result)
}
}
+#if PLATFORM(ANDROID)
+JavaValue jvalueToJavaValue(const jvalue& value, const JavaType& type, bool requireAnnotation)
+#else
JavaValue jvalueToJavaValue(const jvalue& value, const JavaType& type)
+#endif
{
JavaValue result;
result.m_type = type;
@@ -429,7 +433,11 @@ JavaValue jvalueToJavaValue(const jvalue& value, const JavaType& type)
case JavaTypeVoid:
break;
case JavaTypeObject:
+#if PLATFORM(ANDROID)
+ result.m_objectValue = new JavaInstanceJobject(value.l, requireAnnotation);
+#else
result.m_objectValue = new JavaInstanceJobject(value.l);
+#endif
break;
case JavaTypeString:
{
diff --git a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h
index 0282904..47ee45a 100644
--- a/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h
+++ b/Source/WebCore/bridge/jni/v8/JNIUtilityPrivate.h
@@ -41,7 +41,11 @@ class JavaValue;
JavaValue convertNPVariantToJavaValue(NPVariant, const String& javaClass);
void convertJavaValueToNPVariant(JavaValue, NPVariant*);
+#if PLATFORM(ANDROID)
+JavaValue jvalueToJavaValue(const jvalue&, const JavaType&, bool requireAnnotation);
+#else
JavaValue jvalueToJavaValue(const jvalue&, const JavaType&);
+#endif
jvalue javaValueToJvalue(const JavaValue&);
} // namespace Bindings
diff --git a/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp b/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp
index 40bfd63..669eb49 100644
--- a/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp
+++ b/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp
@@ -33,7 +33,18 @@
using namespace JSC::Bindings;
+#if PLATFORM(ANDROID)
+const char kJavaScriptInterfaceAnnotation[] = "android/webkit/JavascriptInterface";
+const char kIsAnnotationPresent[] = "isAnnotationPresent";
+const char kGetMethods[] = "getMethods";
+
+static jclass safeAnnotationClazz = NULL;
+
+JavaClassJobject::JavaClassJobject(jobject anInstance, bool requireAnnotation)
+ : m_requireAnnotation(requireAnnotation)
+#else
JavaClassJobject::JavaClassJobject(jobject anInstance)
+#endif
{
jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
@@ -57,15 +68,28 @@ JavaClassJobject::JavaClassJobject(jobject anInstance)
// Get the methods
jarray methods = static_cast<jarray>(callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;"));
int numMethods = env->GetArrayLength(methods);
+#if PLATFORM(ANDROID)
+ jmethodID isAnnotationPresentMethodID = getAnnotationMethodID(env);
+ if (!isAnnotationPresentMethodID) {
+ LOG_ERROR("unable to find method %s on instance %p", kIsAnnotationPresent, anInstance);
+ return;
+ }
+#endif
for (int i = 0; i < numMethods; i++) {
jobject aJMethod = env->GetObjectArrayElement(static_cast<jobjectArray>(methods), i);
- JavaMethod* aMethod = new JavaMethodJobject(env, aJMethod); // deleted in the JavaClass destructor
- MethodList* methodList = m_methods.get(aMethod->name());
- if (!methodList) {
- methodList = new MethodList();
- m_methods.set(aMethod->name(), methodList);
+#if PLATFORM(ANDROID)
+ if (jsAccessAllowed(env, isAnnotationPresentMethodID, aJMethod)) {
+#endif
+ JavaMethod* aMethod = new JavaMethodJobject(env, aJMethod); // deleted in the JavaClass destructor
+ MethodList* methodList = m_methods.get(aMethod->name());
+ if (!methodList) {
+ methodList = new MethodList();
+ m_methods.set(aMethod->name(), methodList);
+ }
+ methodList->append(aMethod);
+#if PLATFORM(ANDROID)
}
- methodList->append(aMethod);
+#endif
env->DeleteLocalRef(aJMethod);
}
env->DeleteLocalRef(fields);
@@ -87,6 +111,44 @@ JavaClassJobject::~JavaClassJobject()
m_methods.clear();
}
+#if PLATFORM(ANDROID)
+bool JavaClassJobject::jsAccessAllowed(JNIEnv* env, jmethodID mid, jobject aJMethod)
+{
+ if (!m_requireAnnotation)
+ return true;
+ bool accessAllowed = env->CallBooleanMethod(aJMethod, mid, safeAnnotationClazz);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ return false;
+ }
+ return accessAllowed;
+}
+
+jmethodID JavaClassJobject::getAnnotationMethodID(JNIEnv* env)
+{
+ jclass methodClass = env->FindClass("java/lang/reflect/Method");
+ jmethodID mid = 0;
+ if (methodClass)
+ mid = env->GetMethodID(methodClass, kIsAnnotationPresent, "(Ljava/lang/Class;)Z");
+ if (!methodClass || !mid) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ env->DeleteLocalRef(methodClass);
+ return mid;
+}
+
+bool JavaClassJobject::RegisterJavaClassJobject(JNIEnv* env) {
+ safeAnnotationClazz = reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass(kJavaScriptInterfaceAnnotation)));
+ if (!safeAnnotationClazz) {
+ LOG_ERROR("failed to register %s", kJavaScriptInterfaceAnnotation);
+ return false;
+ }
+ return true;
+}
+#endif
+
MethodList JavaClassJobject::methodsNamed(const char* name) const
{
MethodList* methodList = m_methods.get(name);
diff --git a/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h b/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h
index d27ca97..e4035aa 100644
--- a/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h
+++ b/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.h
@@ -37,17 +37,33 @@ namespace Bindings {
class JavaClassJobject : public JavaClass {
public:
+#if PLATFORM(ANDROID)
+ JavaClassJobject(jobject, bool);
+#else
JavaClassJobject(jobject);
+#endif
virtual ~JavaClassJobject();
// JavaClass implementation
virtual MethodList methodsNamed(const char* name) const;
virtual JavaField* fieldNamed(const char* name) const;
+#if PLATFORM(ANDROID)
+ static bool RegisterJavaClassJobject(JNIEnv* env);
+#endif
+
private:
+#if PLATFORM(ANDROID)
+ bool jsAccessAllowed(JNIEnv* env, jmethodID mid, jobject aJMethod);
+ jmethodID getAnnotationMethodID(JNIEnv* env);
+#endif
+
typedef HashMap<WTF::String, MethodList*> MethodListMap;
MethodListMap m_methods;
FieldMap m_fields;
+#if PLATFORM(ANDROID)
+ bool m_requireAnnotation;
+#endif
};
} // namespace Bindings
diff --git a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp
index e7b854d..c97a67f 100644
--- a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp
+++ b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.cpp
@@ -41,8 +41,15 @@
using namespace JSC::Bindings;
+#if PLATFORM(ANDROID)
+JavaInstanceJobject::JavaInstanceJobject(jobject instance, bool requireAnnotation)
+#else
JavaInstanceJobject::JavaInstanceJobject(jobject instance)
+#endif
: m_instance(new JobjectWrapper(instance))
+#if PLATFORM(ANDROID)
+ , m_requireAnnotation(requireAnnotation)
+#endif
{
}
@@ -61,7 +68,11 @@ void JavaInstanceJobject::end()
JavaClass* JavaInstanceJobject::getClass() const
{
if (!m_class)
+#if PLATFORM(ANDROID)
+ m_class = adoptPtr(new JavaClassJobject(javaInstance(), m_requireAnnotation));
+#else
m_class = adoptPtr(new JavaClassJobject(javaInstance()));
+#endif
return m_class.get();
}
@@ -86,7 +97,7 @@ JavaValue JavaInstanceJobject::invokeMethod(const JavaMethod* method, JavaValue*
return JavaValue();
}
- return jvalueToJavaValue(result, method->returnType());
+ return jvalueToJavaValue(result, method->returnType(), m_requireAnnotation);
// END ANDROID
}
@@ -113,7 +124,11 @@ JavaValue JavaInstanceJobject::getField(const JavaField* field)
appendClassName(signature, field->typeClassName());
signature.append(';');
}
+#if PLATFORM(ANDROID)
+ return jvalueToJavaValue(getJNIField(javaInstance(), field->type(), field->name().utf8().data(), signature.toString().utf8().data()), field->type(), m_requireAnnotation);
+#else
return jvalueToJavaValue(getJNIField(javaInstance(), field->type(), field->name().utf8().data(), signature.toString().utf8().data()), field->type());
+#endif
}
#endif // ENABLE(JAVA_BRIDGE)
diff --git a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h
index 255c190..77dcf28 100644
--- a/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h
+++ b/Source/WebCore/bridge/jni/v8/JavaInstanceJobjectV8.h
@@ -48,8 +48,11 @@ namespace Bindings {
class JavaInstanceJobject : public JavaInstance {
public:
+#if PLATFORM(ANDROID)
+ JavaInstanceJobject(jobject instance, bool requireAnnotation);
+#else
JavaInstanceJobject(jobject instance);
-
+#endif
// JavaInstance implementation
virtual JavaClass* getClass() const;
// ANDROID
@@ -64,6 +67,9 @@ public:
protected:
RefPtr<JobjectWrapper> m_instance;
mutable OwnPtr<JavaClass> m_class;
+#if PLATFORM(ANDROID)
+ bool m_requireAnnotation;
+#endif
};
} // namespace Bindings