Skip to content

Commit b679dd1

Browse files
LeviticusMBjoeferner
authored andcommitted
Actually test (and handle) argument count mismatch.
Always pass strings as const-ref and don't modify caller values, for correct error messages.
1 parent 2d0fbdd commit b679dd1

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

src/utils.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ jvalueType javaGetType(JNIEnv *env, jclass type) {
213213
}
214214
}
215215

216-
jclass javaFindClass(JNIEnv* env, std::string& className) {
216+
jclass javaFindClass(JNIEnv* env, const std::string& className) {
217217
std::string searchClassName = className;
218218
std::replace(searchClassName.begin(), searchClassName.end(), '.', '/');
219219

@@ -234,7 +234,7 @@ jclass javaFindClass(JNIEnv* env, std::string& className) {
234234
return clazz;
235235
}
236236

237-
jobject javaFindField(JNIEnv* env, jclass clazz, std::string& fieldName) {
237+
jobject javaFindField(JNIEnv* env, jclass clazz, const std::string& fieldName) {
238238
jobject result = NULL;
239239
jclass clazzclazz = env->GetObjectClass(clazz);
240240
jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
@@ -789,18 +789,18 @@ jobjectArray javaObjectArrayToClasses(JNIEnv *env, jobjectArray objs) {
789789
return results;
790790
}
791791

792-
jobject javaFindMethod(JNIEnv *env, jclass clazz, std::string& methodName, jobjectArray methodArgs) {
792+
jobject javaFindMethod(JNIEnv *env, jclass clazz, const std::string& methodName, jobjectArray methodArgs) {
793793
std::string::size_type parenLoc = methodName.find("(");
794794
if(parenLoc != std::string::npos) {
795795
jobject method = NULL;
796796

797797
std::string methodSig = methodName.substr(parenLoc);
798-
methodName = methodName.substr(0, parenLoc);
799-
jmethodID methodID = env->GetStaticMethodID(clazz, methodName.c_str(), methodSig.c_str());
798+
std::string methodRealName = methodName.substr(0, parenLoc);
799+
jmethodID methodID = env->GetStaticMethodID(clazz, methodRealName.c_str(), methodSig.c_str());
800800
if(methodID != 0) {
801801
method = env->ToReflectedMethod(clazz, methodID, true);
802802
} else {
803-
methodID = env->GetMethodID(clazz, methodName.c_str(), methodSig.c_str());
803+
methodID = env->GetMethodID(clazz, methodRealName.c_str(), methodSig.c_str());
804804
if(methodID != 0) {
805805
method = env->ToReflectedMethod(clazz, methodID, true);
806806
}
@@ -810,6 +810,10 @@ jobject javaFindMethod(JNIEnv *env, jclass clazz, std::string& methodName, jobje
810810
// cast arguments
811811
if(method != NULL) {
812812
javaCastArguments(env, methodArgs, method);
813+
if(env->ExceptionCheck()) {
814+
env->ExceptionClear();
815+
method = NULL;
816+
}
813817
}
814818

815819
return method;
@@ -856,14 +860,20 @@ int dynamicProxyDataVerify(DynamicProxyData* data) {
856860
return 0;
857861
}
858862

859-
std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string methodName, bool constructor, Nan::NAN_METHOD_ARGS_TYPE args, int argStart, int argEnd) {
863+
std::string methodNotFoundToString(JNIEnv *env, jclass clazz, const std::string& methodNameSig, bool constructor, Nan::NAN_METHOD_ARGS_TYPE args, int argStart, int argEnd) {
860864
std::ostringstream startOfMessage;
861865
std::ostringstream msg;
866+
std::string methodName = methodNameSig.substr(0, methodNameSig.find('('));
862867

863868
jclass classClazz = env->FindClass("java/lang/Class");
864869
jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;");
865870

866-
startOfMessage << "Could not find method \"" << methodName.c_str() << "(";
871+
if (methodName != methodNameSig) {
872+
startOfMessage << "Could not find method for signature \"" << methodNameSig.c_str() << "\" and arguments \"(";
873+
} else {
874+
startOfMessage << "Could not find method \"" << methodName.c_str() << "(";
875+
}
876+
867877
for(int i=argStart; i<argEnd; i++) {
868878
jobject val = v8ToJava(env, args[i]);
869879
if(i != argStart) {

src/utils.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ jobject longToJavaLongObj(JNIEnv *env, jlong l);
8080
jarray javaGetArgsForMethod(JNIEnv *env, jobject method, jarray args);
8181
jarray javaGetArgsForConstructor(JNIEnv *env, jobject method, jarray args);
8282

83-
jclass javaFindClass(JNIEnv* env, std::string& className);
84-
jobject javaFindField(JNIEnv* env, jclass clazz, std::string& fieldName);
85-
jobject javaFindMethod(JNIEnv *env, jclass clazz, std::string& methodName, jobjectArray methodArgs);
83+
jclass javaFindClass(JNIEnv* env, const std::string& className);
84+
jobject javaFindField(JNIEnv* env, jclass clazz, const std::string& fieldName);
85+
jobject javaFindMethod(JNIEnv *env, jclass clazz, const std::string& methodName, jobjectArray methodArgs);
8686
jobject javaFindConstructor(JNIEnv *env, jclass clazz, jobjectArray methodArgs);
8787
void javaCastArguments(JNIEnv *env, jobjectArray methodArgs, jobject method);
8888

@@ -97,7 +97,7 @@ void SetHiddenValue(v8::NumberObject*, v8::Local<v8::String> key, v8::Local<v8::
9797
assert(false); \
9898
}
9999

100-
std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string methodName, bool constructor, Nan::NAN_METHOD_ARGS_TYPE args, int argStart, int argEnd);
100+
std::string methodNotFoundToString(JNIEnv *env, jclass clazz, const std::string& methodNameSig, bool constructor, Nan::NAN_METHOD_ARGS_TYPE args, int argStart, int argEnd);
101101

102102
void unref(DynamicProxyData* dynamicProxyData);
103103

test/java-ambiguousMethod-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ exports['Java - Call Ambiguous Method'] = nodeunit.testCase({
2828

2929
"staticMethodAmbiguous (sync) - method failed because argument count mismatch": function(test) {
3030
try {
31-
java.callStaticMethodSync('Test', 'staticMethodAmbiguous(Ljava/lang/String;)I', 1, 2);
31+
java.callStaticMethodSync('Test', 'staticMethodAmbiguous(Ljava/lang/Integer;)I', 1, 2);
3232
test.fail("should throw argument length mismatch");
3333
} catch (e) {
3434
console.log(e);
@@ -61,7 +61,7 @@ exports['Java - Call Ambiguous Method'] = nodeunit.testCase({
6161
},
6262

6363
"staticMethodAmbiguous - method argument count mismatch": function(test) {
64-
java.callStaticMethod('Test', 'staticMethodAmbiguous(Ljava/lang/String;)I', 1, 2, function(err, result) {
64+
java.callStaticMethod('Test', 'staticMethodAmbiguous(Ljava/lang/Integer;)I', 1, 2, function(err, result) {
6565
test.ok(err);
6666
console.log(err);
6767
test.done();
@@ -96,7 +96,7 @@ exports['Java - Call Ambiguous Method'] = nodeunit.testCase({
9696
"methodAmbiguous (sync) - method failed because argument count mismatch": function(test) {
9797
var myTest = java.newInstanceSync("Test");
9898
try {
99-
java.callMethodSync(myTest, 'methodAmbiguous(Ljava/lang/String;)I', 1, 2);
99+
java.callMethodSync(myTest, 'methodAmbiguous(Ljava/lang/Integer;)I', 1, 2);
100100
test.fail("should throw argument length mismatch");
101101
} catch (e) {
102102
console.log(e);

0 commit comments

Comments
 (0)