summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp
diff options
context:
space:
mode:
authorSelim Gurun <sgurun@google.com>2012-09-04 16:31:02 -0700
committerSelim Gurun <sgurun@google.com>2012-09-10 16:39:35 -0700
commitf2d8c5bed31609d7d6e3ae77f33e90ea7f888eb3 (patch)
treef0eaf8dc0c087e6961ef36fc9250bdda15ee17f5 /Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp
parent61df0147f508e20bd22fab568b7c8b3c405cfad5 (diff)
downloadexternal_webkit-f2d8c5bed31609d7d6e3ae77f33e90ea7f888eb3.zip
external_webkit-f2d8c5bed31609d7d6e3ae77f33e90ea7f888eb3.tar.gz
external_webkit-f2d8c5bed31609d7d6e3ae77f33e90ea7f888eb3.tar.bz2
Control access to inherited methods of jsinterface objects
Bug: 7073422 Use a flag and annotation for allowing access to inherited methods of jsinterface objects. When flag is false, no annotation is needed. When flag is true, annotation is needed for allowing access to inherited methods. Change-Id: I610119dc5410d8df1962fa9dbea09866f81d374c
Diffstat (limited to 'Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp')
-rw-r--r--Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp74
1 files changed, 68 insertions, 6 deletions
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);