Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: content/browser/renderer_host/java/java_bound_object.cc

Issue 10793035: Add flag to Java -> JavaScript to disable exposing inherited methods. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed commit description. Rebased. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/renderer_host/java/java_bound_object.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/java/java_bound_object.h" 5 #include "content/browser/renderer_host/java/java_bound_object.h"
6 6
7 #include "base/android/jni_android.h" 7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h" 8 #include "base/android/jni_string.h"
9 #include "base/memory/singleton.h" 9 #include "base/memory/singleton.h"
10 #include "base/string_number_conversions.h" 10 #include "base/string_number_conversions.h"
(...skipping 16 matching lines...) Expand all
27 // http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. 27 // http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS.
28 28
29 // Note that in some cases, we differ from from the spec in order to maintain 29 // Note that in some cases, we differ from from the spec in order to maintain
30 // existing behavior. These areas are marked LIVECONNECT_COMPLIANCE. We may 30 // existing behavior. These areas are marked LIVECONNECT_COMPLIANCE. We may
31 // revisit this decision in the future. 31 // revisit this decision in the future.
32 32
33 namespace { 33 namespace {
34 34
35 const char kJavaLangClass[] = "java/lang/Class"; 35 const char kJavaLangClass[] = "java/lang/Class";
36 const char kJavaLangObject[] = "java/lang/Object"; 36 const char kJavaLangObject[] = "java/lang/Object";
37 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method";
37 const char kGetClass[] = "getClass"; 38 const char kGetClass[] = "getClass";
39 const char kGetDeclaredMethods[] = "getDeclaredMethods";
38 const char kGetMethods[] = "getMethods"; 40 const char kGetMethods[] = "getMethods";
41 const char kGetModifiers[] = "getModifiers";
42 const char kReturningInteger[] = "()I";
39 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;"; 43 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;";
40 const char kReturningJavaLangReflectMethodArray[] = 44 const char kReturningJavaLangReflectMethodArray[] =
41 "()[Ljava/lang/reflect/Method;"; 45 "()[Ljava/lang/reflect/Method;";
42 46
47 // This constant represents the value at java.lang.reflect.Modifier.PUBLIC.
48 const int kJavaPublicModifier = 1;
49
43 // Our special NPObject type. We extend an NPObject with a pointer to a 50 // Our special NPObject type. We extend an NPObject with a pointer to a
44 // JavaBoundObject. We also add static methods for each of the NPObject 51 // JavaBoundObject. We also add static methods for each of the NPObject
45 // callbacks, which are registered by our NPClass. These methods simply 52 // callbacks, which are registered by our NPClass. These methods simply
46 // delegate to the private implementation methods of JavaBoundObject. 53 // delegate to the private implementation methods of JavaBoundObject.
47 struct JavaNPObject : public NPObject { 54 struct JavaNPObject : public NPObject {
48 JavaBoundObject* bound_object; 55 JavaBoundObject* bound_object;
49 56
50 static const NPClass kNPClass; 57 static const NPClass kNPClass;
51 58
52 static NPObject* Allocate(NPP npp, NPClass* np_class); 59 static NPObject* Allocate(NPP npp, NPClass* np_class);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 // that the property is undefined. Spec requires supporting this correctly. 120 // that the property is undefined. Spec requires supporting this correctly.
114 return false; 121 return false;
115 } 122 }
116 123
117 // Calls a Java method through JNI. If the Java method raises an uncaught 124 // Calls a Java method through JNI. If the Java method raises an uncaught
118 // exception, it is cleared and this method returns false. Otherwise, this 125 // exception, it is cleared and this method returns false. Otherwise, this
119 // method returns true and the Java method's return value is provided as an 126 // method returns true and the Java method's return value is provided as an
120 // NPVariant. Note that this method does not do any type coercion. The Java 127 // NPVariant. Note that this method does not do any type coercion. The Java
121 // return value is simply converted to the corresponding NPAPI type. 128 // return value is simply converted to the corresponding NPAPI type.
122 bool CallJNIMethod(jobject object, const JavaType& return_type, jmethodID id, 129 bool CallJNIMethod(jobject object, const JavaType& return_type, jmethodID id,
123 jvalue* parameters, NPVariant* result) { 130 jvalue* parameters, NPVariant* result,
131 bool allow_inherited_methods) {
124 JNIEnv* env = AttachCurrentThread(); 132 JNIEnv* env = AttachCurrentThread();
125 switch (return_type.type) { 133 switch (return_type.type) {
126 case JavaType::TypeBoolean: 134 case JavaType::TypeBoolean:
127 BOOLEAN_TO_NPVARIANT(env->CallBooleanMethodA(object, id, parameters), 135 BOOLEAN_TO_NPVARIANT(env->CallBooleanMethodA(object, id, parameters),
128 *result); 136 *result);
129 break; 137 break;
130 case JavaType::TypeByte: 138 case JavaType::TypeByte:
131 INT32_TO_NPVARIANT(env->CallByteMethodA(object, id, parameters), *result); 139 INT32_TO_NPVARIANT(env->CallByteMethodA(object, id, parameters), *result);
132 break; 140 break;
133 case JavaType::TypeChar: 141 case JavaType::TypeChar:
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 // first. 202 // first.
195 jobject java_object = env->CallObjectMethodA(object, id, parameters); 203 jobject java_object = env->CallObjectMethodA(object, id, parameters);
196 if (base::android::ClearException(env)) { 204 if (base::android::ClearException(env)) {
197 return false; 205 return false;
198 } 206 }
199 ScopedJavaLocalRef<jobject> scoped_java_object(env, java_object); 207 ScopedJavaLocalRef<jobject> scoped_java_object(env, java_object);
200 if (!scoped_java_object.obj()) { 208 if (!scoped_java_object.obj()) {
201 NULL_TO_NPVARIANT(*result); 209 NULL_TO_NPVARIANT(*result);
202 break; 210 break;
203 } 211 }
204 OBJECT_TO_NPVARIANT(JavaBoundObject::Create(scoped_java_object), *result); 212 OBJECT_TO_NPVARIANT(JavaBoundObject::Create(scoped_java_object,
213 allow_inherited_methods),
214 *result);
205 break; 215 break;
206 } 216 }
207 } 217 }
208 return !base::android::ClearException(env); 218 return !base::android::ClearException(env);
209 } 219 }
210 220
211 jvalue CoerceJavaScriptNumberToJavaValue(const NPVariant& variant, 221 jvalue CoerceJavaScriptNumberToJavaValue(const NPVariant& variant,
212 const JavaType& target_type, 222 const JavaType& target_type,
213 bool coerce_to_string) { 223 bool coerce_to_string) {
214 // See http://jdk6.java.net/plugin2/liveconnect/#JS_NUMBER_VALUES. 224 // See http://jdk6.java.net/plugin2/liveconnect/#JS_NUMBER_VALUES.
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 return CoerceJavaScriptNullOrUndefinedToJavaValue(variant, target_type, 720 return CoerceJavaScriptNullOrUndefinedToJavaValue(variant, target_type,
711 coerce_to_string); 721 coerce_to_string);
712 } 722 }
713 NOTREACHED(); 723 NOTREACHED();
714 return jvalue(); 724 return jvalue();
715 } 725 }
716 726
717 } // namespace 727 } // namespace
718 728
719 729
720 NPObject* JavaBoundObject::Create(const JavaRef<jobject>& object) { 730 NPObject* JavaBoundObject::Create(const JavaRef<jobject>& object,
731 bool allow_inherited_methods) {
721 // The first argument (a plugin's instance handle) is passed through to the 732 // The first argument (a plugin's instance handle) is passed through to the
722 // allocate function directly, and we don't use it, so it's ok to be 0. 733 // allocate function directly, and we don't use it, so it's ok to be 0.
723 // The object is created with a ref count of one. 734 // The object is created with a ref count of one.
724 NPObject* np_object = WebBindings::createObject(0, const_cast<NPClass*>( 735 NPObject* np_object = WebBindings::createObject(0, const_cast<NPClass*>(
725 &JavaNPObject::kNPClass)); 736 &JavaNPObject::kNPClass));
726 // The NPObject takes ownership of the JavaBoundObject. 737 // The NPObject takes ownership of the JavaBoundObject.
727 reinterpret_cast<JavaNPObject*>(np_object)->bound_object = 738 reinterpret_cast<JavaNPObject*>(np_object)->bound_object =
728 new JavaBoundObject(object); 739 new JavaBoundObject(object, allow_inherited_methods);
729 return np_object; 740 return np_object;
730 } 741 }
731 742
732 JavaBoundObject::JavaBoundObject(const JavaRef<jobject>& object) 743 JavaBoundObject::JavaBoundObject(const JavaRef<jobject>& object,
733 : java_object_(object) { 744 bool allow_inherited_methods)
745 : java_object_(object),
746 are_methods_set_up_(false),
747 allow_inherited_methods_(allow_inherited_methods) {
734 // We don't do anything with our Java object when first created. We do it all 748 // We don't do anything with our Java object when first created. We do it all
735 // lazily when a method is first invoked. 749 // lazily when a method is first invoked.
736 } 750 }
737 751
738 JavaBoundObject::~JavaBoundObject() { 752 JavaBoundObject::~JavaBoundObject() {
739 } 753 }
740 754
741 jobject JavaBoundObject::GetJavaObject(NPObject* object) { 755 jobject JavaBoundObject::GetJavaObject(NPObject* object) {
742 DCHECK_EQ(&JavaNPObject::kNPClass, object->_class); 756 DCHECK_EQ(&JavaNPObject::kNPClass, object->_class);
743 JavaBoundObject* jbo = reinterpret_cast<JavaNPObject*>(object)->bound_object; 757 JavaBoundObject* jbo = reinterpret_cast<JavaNPObject*>(object)->bound_object;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 // Coerce 790 // Coerce
777 std::vector<jvalue> parameters(arg_count); 791 std::vector<jvalue> parameters(arg_count);
778 for (size_t i = 0; i < arg_count; ++i) { 792 for (size_t i = 0; i < arg_count; ++i) {
779 parameters[i] = CoerceJavaScriptValueToJavaValue(args[i], 793 parameters[i] = CoerceJavaScriptValueToJavaValue(args[i],
780 method->parameter_type(i), 794 method->parameter_type(i),
781 true); 795 true);
782 } 796 }
783 797
784 // Call 798 // Call
785 bool ok = CallJNIMethod(java_object_.obj(), method->return_type(), 799 bool ok = CallJNIMethod(java_object_.obj(), method->return_type(),
786 method->id(), &parameters[0], result); 800 method->id(), &parameters[0], result,
801 allow_inherited_methods_);
787 802
788 // Now that we're done with the jvalue, release any local references created 803 // Now that we're done with the jvalue, release any local references created
789 // by CoerceJavaScriptValueToJavaValue(). 804 // by CoerceJavaScriptValueToJavaValue().
790 JNIEnv* env = AttachCurrentThread(); 805 JNIEnv* env = AttachCurrentThread();
791 for (size_t i = 0; i < arg_count; ++i) { 806 for (size_t i = 0; i < arg_count; ++i) {
792 ReleaseJavaValueIfRequired(env, &parameters[i], method->parameter_type(i)); 807 ReleaseJavaValueIfRequired(env, &parameters[i], method->parameter_type(i));
793 } 808 }
794 809
795 return ok; 810 return ok;
796 } 811 }
797 812
798 void JavaBoundObject::EnsureMethodsAreSetUp() const { 813 void JavaBoundObject::EnsureMethodsAreSetUp() const {
799 if (!methods_.empty()) { 814 if (are_methods_set_up_)
800 return; 815 return;
801 } 816 are_methods_set_up_ = true;
802 817
803 JNIEnv* env = AttachCurrentThread(); 818 JNIEnv* env = AttachCurrentThread();
804 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( 819 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>(
805 env->CallObjectMethod(java_object_.obj(), GetMethodIDFromClassName( 820 env->CallObjectMethod(java_object_.obj(), GetMethodIDFromClassName(
806 env, 821 env,
807 kJavaLangObject, 822 kJavaLangObject,
808 kGetClass, 823 kGetClass,
809 kReturningJavaLangClass)))); 824 kReturningJavaLangClass))));
825
826 const char* get_method = allow_inherited_methods_ ?
827 kGetMethods : kGetDeclaredMethods;
828
810 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>( 829 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>(
811 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( 830 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName(
812 env, 831 env,
813 kJavaLangClass, 832 kJavaLangClass,
814 kGetMethods, 833 get_method,
815 kReturningJavaLangReflectMethodArray)))); 834 kReturningJavaLangReflectMethodArray))));
835
816 size_t num_methods = env->GetArrayLength(methods.obj()); 836 size_t num_methods = env->GetArrayLength(methods.obj());
817 DCHECK(num_methods) << "Java objects always have public methods"; 837 if (num_methods <= 0)
838 return;
839
818 for (size_t i = 0; i < num_methods; ++i) { 840 for (size_t i = 0; i < num_methods; ++i) {
819 ScopedJavaLocalRef<jobject> java_method( 841 ScopedJavaLocalRef<jobject> java_method(
820 env, 842 env,
821 env->GetObjectArrayElement(methods.obj(), i)); 843 env->GetObjectArrayElement(methods.obj(), i));
822 JavaMethod* method = new JavaMethod(java_method); 844
823 methods_.insert(std::make_pair(method->name(), method)); 845 bool is_method_allowed = true;
846 if (!allow_inherited_methods_) {
847 jint modifiers = env->CallIntMethod(java_method.obj(),
848 GetMethodIDFromClassName(
849 env,
850 kJavaLangReflectMethod,
851 kGetModifiers,
852 kReturningInteger));
joth 2012/07/18 17:28:39 after the fact -- just noticed this is non-standar
853 is_method_allowed &= (modifiers & kJavaPublicModifier);
854 }
855
856 if (is_method_allowed) {
857 JavaMethod* method = new JavaMethod(java_method);
858 methods_.insert(std::make_pair(method->name(), method));
859 }
824 } 860 }
825 } 861 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/java/java_bound_object.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698