diff options
author | Selim Gurun <sgurun@google.com> | 2012-09-04 16:31:02 -0700 |
---|---|---|
committer | Selim Gurun <sgurun@google.com> | 2012-09-10 16:39:35 -0700 |
commit | f2d8c5bed31609d7d6e3ae77f33e90ea7f888eb3 (patch) | |
tree | f0eaf8dc0c087e6961ef36fc9250bdda15ee17f5 /Source/WebCore/bridge/jni/v8/JavaClassJobjectV8.cpp | |
parent | 61df0147f508e20bd22fab568b7c8b3c405cfad5 (diff) | |
download | external_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.cpp | 74 |
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); |