summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2017-04-20 15:16:44 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2017-04-20 15:16:45 +0000
commit38870a8a2717ccf1bcd3faddc53b1999985bb29f (patch)
treeb79db0f347eae175d590de844797d1be2ff58d70 /runtime/class_linker.cc
parentaa03f6fa38da0166790f2b22b679e6568ad56f7d (diff)
parent5fdd778d07e0c87203b3c9d776fda3544c51a3a4 (diff)
Merge "Add descriptor validation to ClassLinker::FindClass()."
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc18
1 files changed, 17 insertions, 1 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 4bc8e8efba..1d0684202c 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2592,9 +2592,25 @@ mirror::Class* ClassLinker::FindClass(Thread* self,
return nullptr;
}
+ // Inlined DescriptorToDot(descriptor) with extra validation.
+ //
+ // Throw NoClassDefFoundError early rather than potentially load a class only to fail
+ // the DescriptorEquals() check below and give a confusing error message. For example,
+ // when native code erroneously calls JNI GetFieldId() with signature "java/lang/String"
+ // instead of "Ljava/lang/String;", the message below using the "dot" names would be
+ // "class loader [...] returned class java.lang.String instead of java.lang.String".
+ size_t descriptor_length = strlen(descriptor);
+ if (UNLIKELY(descriptor[0] != 'L') ||
+ UNLIKELY(descriptor[descriptor_length - 1] != ';') ||
+ UNLIKELY(memchr(descriptor + 1, '.', descriptor_length - 2) != nullptr)) {
+ ThrowNoClassDefFoundError("Invalid descriptor: %s.", descriptor);
+ return nullptr;
+ }
+ std::string class_name_string(descriptor + 1, descriptor_length - 2);
+ std::replace(class_name_string.begin(), class_name_string.end(), '/', '.');
+
ScopedLocalRef<jobject> class_loader_object(
soa.Env(), soa.AddLocalReference<jobject>(class_loader.Get()));
- std::string class_name_string(DescriptorToDot(descriptor));
ScopedLocalRef<jobject> result(soa.Env(), nullptr);
{
ScopedThreadStateChange tsc(self, kNative);