hotspot/src/share/vm/classfile/classLoader.cpp
changeset 39216 40c3d66352ae
parent 39210 178947361a68
child 39223 af5506aae343
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Tue Jun 07 00:57:23 2016 +0000
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Tue Jun 07 11:39:47 2016 -0400
@@ -181,26 +181,59 @@
 }
 
 // Used to obtain the package name from a fully qualified class name.
-// It is the responsibility of the caller to establish ResourceMark.
-const char* ClassLoader::package_from_name(const char* class_name) {
-  const char* last_slash = strrchr(class_name, '/');
+// It is the responsibility of the caller to establish a ResourceMark.
+const char* ClassLoader::package_from_name(const char* const class_name, bool* bad_class_name) {
+  if (class_name == NULL) {
+    if (bad_class_name != NULL) {
+      *bad_class_name = true;
+    }
+    return NULL;
+  }
+
+  if (bad_class_name != NULL) {
+    *bad_class_name = false;
+  }
+
+  const char* const last_slash = strrchr(class_name, '/');
   if (last_slash == NULL) {
     // No package name
     return NULL;
   }
-  int length = last_slash - class_name;
+
+  char* class_name_ptr = (char*) class_name;
+  // Skip over '['s
+  if (*class_name_ptr == '[') {
+    do {
+      class_name_ptr++;
+    } while (*class_name_ptr == '[');
 
-  // A class name could have just the slash character in the name,
-  // resulting in a negative length.
+    // Fully qualified class names should not contain a 'L'.
+    // Set bad_class_name to true to indicate that the package name
+    // could not be obtained due to an error condition.
+    // In this situation, is_same_class_package returns false.
+    if (*class_name_ptr == 'L') {
+      if (bad_class_name != NULL) {
+        *bad_class_name = true;
+      }
+      return NULL;
+    }
+  }
+
+  int length = last_slash - class_name_ptr;
+
+  // A class name could have just the slash character in the name.
   if (length <= 0) {
     // No package name
+    if (bad_class_name != NULL) {
+      *bad_class_name = true;
+    }
     return NULL;
   }
 
   // drop name after last slash (including slash)
   // Ex., "java/lang/String.class" => "java/lang"
   char* pkg_name = NEW_RESOURCE_ARRAY(char, length + 1);
-  strncpy(pkg_name, class_name, length);
+  strncpy(pkg_name, class_name_ptr, length);
   *(pkg_name+length) = '\0';
 
   return (const char *)pkg_name;
@@ -1117,13 +1150,11 @@
   assert(fullq_class_name != NULL, "just checking");
 
   // Get package name from fully qualified class name.
-  const char *cp = strrchr(fullq_class_name, '/');
+  ResourceMark rm;
+  const char *cp = package_from_name(fullq_class_name);
   if (cp != NULL) {
-    int len = cp - fullq_class_name;
-    PackageEntryTable* pkg_entry_tbl =
-      ClassLoaderData::the_null_class_loader_data()->packages();
-    TempNewSymbol pkg_symbol =
-      SymbolTable::new_symbol(fullq_class_name, len, CHECK_false);
+    PackageEntryTable* pkg_entry_tbl = ClassLoaderData::the_null_class_loader_data()->packages();
+    TempNewSymbol pkg_symbol = SymbolTable::new_symbol(cp, CHECK_false);
     PackageEntry* pkg_entry = pkg_entry_tbl->lookup_only(pkg_symbol);
     if (pkg_entry != NULL) {
       assert(classpath_index != -1, "Unexpected classpath_index");
@@ -1231,11 +1262,9 @@
   // jimage, it is determined by the class path entry.
   jshort loader_type = ClassLoader::APP_LOADER;
   if (e->is_jrt()) {
-    int length = 0;
-    const jbyte* pkg_string = InstanceKlass::package_from_name(class_name, length);
-    if (pkg_string != NULL) {
-      ResourceMark rm;
-      TempNewSymbol pkg_name = SymbolTable::new_symbol((const char*)pkg_string, length, THREAD);
+    ResourceMark rm;
+    TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK_0);
+    if (pkg_name != NULL) {
       const char* pkg_name_C_string = (const char*)(pkg_name->as_C_string());
       ClassPathImageEntry* cpie = (ClassPathImageEntry*)e;
       JImageFile* jimage = cpie->jimage();