8338888: SystemDictionary::class_name_symbol has incorrect length check
Reviewed-by: stuefe, kbarrett, coleenp
This commit is contained in:
parent
a8ac28725b
commit
72a49005ee
@ -261,17 +261,32 @@ Symbol* SystemDictionary::class_name_symbol(const char* name, Symbol* exception,
|
||||
if (name == nullptr) {
|
||||
THROW_MSG_NULL(exception, "No class name given");
|
||||
}
|
||||
if ((int)strlen(name) > Symbol::max_length()) {
|
||||
size_t name_len = strlen(name);
|
||||
if (name_len > static_cast<size_t>(Symbol::max_length())) {
|
||||
// It's impossible to create this class; the name cannot fit
|
||||
// into the constant pool.
|
||||
Exceptions::fthrow(THREAD_AND_LOCATION, exception,
|
||||
"Class name exceeds maximum length of %d: %s",
|
||||
Symbol::max_length(),
|
||||
name);
|
||||
// into the constant pool. If necessary report an abridged name
|
||||
// in the exception message.
|
||||
if (name_len > static_cast<size_t>(MaxStringPrintSize)) {
|
||||
Exceptions::fthrow(THREAD_AND_LOCATION, exception,
|
||||
"Class name exceeds maximum length of %d: %.*s ... (%zu characters omitted) ... %.*s",
|
||||
Symbol::max_length(),
|
||||
MaxStringPrintSize / 2,
|
||||
name,
|
||||
name_len - 2 * (MaxStringPrintSize / 2), // allows for odd value
|
||||
MaxStringPrintSize / 2,
|
||||
name + name_len - MaxStringPrintSize / 2);
|
||||
}
|
||||
else {
|
||||
Exceptions::fthrow(THREAD_AND_LOCATION, exception,
|
||||
"Class name exceeds maximum length of %d: %s",
|
||||
Symbol::max_length(),
|
||||
name);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
// Callers should ensure that the name is never an illegal UTF8 string.
|
||||
assert(UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false),
|
||||
assert(UTF8::is_legal_utf8((const unsigned char*)name,
|
||||
static_cast<int>(name_len), false),
|
||||
"Class name is not a valid utf8 string.");
|
||||
|
||||
// Make a new symbol for the class name.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,12 +23,12 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8056900
|
||||
* @bug 8056900 8338888
|
||||
* @summary Verifies message returned with NoClassDefFoundError exception.
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.compiler
|
||||
* @run main/native NoClassDefFoundErrorTest
|
||||
* @run main/native/othervm -Xlog:exceptions=info NoClassDefFoundErrorTest
|
||||
*/
|
||||
|
||||
import jdk.test.lib.compiler.InMemoryJavaCompiler;
|
||||
@ -36,8 +36,14 @@ import jdk.internal.misc.Unsafe;
|
||||
|
||||
public class NoClassDefFoundErrorTest {
|
||||
|
||||
// Use the specified name
|
||||
static native void callDefineClass(String className);
|
||||
static native void callFindClass(String className);
|
||||
// Use a name longer than a Java string - returns false
|
||||
// if native allocation failed.
|
||||
static native boolean tryCallDefineClass();
|
||||
static native boolean tryCallFindClass();
|
||||
|
||||
static {
|
||||
System.loadLibrary("NoClassDefFoundErrorTest");
|
||||
}
|
||||
@ -54,7 +60,7 @@ public class NoClassDefFoundErrorTest {
|
||||
tooBigClassName = tooBigClassName.append(tooBigClassName);
|
||||
}
|
||||
|
||||
// Test JVM_DefineClass() with long name.
|
||||
System.out.println("Test JVM_DefineClass() with long name");
|
||||
try {
|
||||
unsafe.defineClass(tooBigClassName.toString(), klassbuf, 4, klassbuf.length - 4, null, null);
|
||||
throw new RuntimeException("defineClass did not throw expected NoClassDefFoundError");
|
||||
@ -64,7 +70,7 @@ public class NoClassDefFoundErrorTest {
|
||||
}
|
||||
}
|
||||
|
||||
// Test JNI_DefineClass() with long name.
|
||||
System.out.println("Test JNI_DefineClass() with long name");
|
||||
try {
|
||||
callDefineClass(tooBigClassName.toString());
|
||||
throw new RuntimeException("DefineClass did not throw expected NoClassDefFoundError");
|
||||
@ -74,17 +80,17 @@ public class NoClassDefFoundErrorTest {
|
||||
}
|
||||
}
|
||||
|
||||
// Test JNI_FindClass() with long name.
|
||||
System.out.println("Test JNI_FindClass() with long name");
|
||||
try {
|
||||
callFindClass(tooBigClassName.toString());
|
||||
throw new RuntimeException("DefineClass did not throw expected NoClassDefFoundError");
|
||||
throw new RuntimeException("FindClass did not throw expected NoClassDefFoundError");
|
||||
} catch (NoClassDefFoundError e) {
|
||||
if (!e.getMessage().contains("Class name exceeds maximum length of ")) {
|
||||
throw new RuntimeException("Wrong NoClassDefFoundError: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Test JNI_FindClass() with null name.
|
||||
System.out.println("Test JNI_FindClass() with null name");
|
||||
try {
|
||||
callFindClass(null);
|
||||
throw new RuntimeException("FindClass did not throw expected NoClassDefFoundError");
|
||||
@ -93,5 +99,31 @@ public class NoClassDefFoundErrorTest {
|
||||
throw new RuntimeException("Wrong NoClassDefFoundError: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Test JNI_DefineClass() with giant name");
|
||||
try {
|
||||
if (tryCallDefineClass()) {
|
||||
throw new RuntimeException("DefineClass did not throw expected NoClassDefFoundError");
|
||||
} else {
|
||||
System.out.println("Test skipped due to native allocation failure");
|
||||
}
|
||||
} catch (NoClassDefFoundError e) {
|
||||
if (!e.getMessage().contains("Class name exceeds maximum length of ")) {
|
||||
throw new RuntimeException("Wrong NoClassDefFoundError: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Test JNI_FindClass() with giant name");
|
||||
try {
|
||||
if (tryCallFindClass()) {
|
||||
throw new RuntimeException("FindClass did not throw expected NoClassDefFoundError");
|
||||
} else {
|
||||
System.out.println("Test skipped due to native allocation failure");
|
||||
}
|
||||
} catch (NoClassDefFoundError e) {
|
||||
if (!e.getMessage().contains("Class name exceeds maximum length of ")) {
|
||||
throw new RuntimeException("Wrong NoClassDefFoundError: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,6 +22,10 @@
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_NoClassDefFoundErrorTest_callDefineClass(JNIEnv *env, jclass klass, jstring className) {
|
||||
@ -42,3 +46,34 @@ Java_NoClassDefFoundErrorTest_callFindClass(JNIEnv *env, jclass klass, jstring c
|
||||
}
|
||||
|
||||
|
||||
static char* giant_string() {
|
||||
size_t len = ((size_t)INT_MAX) + 3;
|
||||
char* c_name = malloc(len * sizeof(char));
|
||||
if (c_name != NULL) {
|
||||
memset(c_name, 'Y', len - 1);
|
||||
c_name[len - 1] = '\0';
|
||||
}
|
||||
return c_name;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_NoClassDefFoundErrorTest_tryCallDefineClass(JNIEnv *env, jclass klass) {
|
||||
char* c_name = giant_string();
|
||||
if (c_name != NULL) {
|
||||
(*env)->DefineClass(env, c_name, NULL, NULL, 0);
|
||||
free(c_name);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_NoClassDefFoundErrorTest_tryCallFindClass(JNIEnv *env, jclass klass) {
|
||||
char* c_name = giant_string();
|
||||
if (c_name != NULL) {
|
||||
jclass cls = (*env)->FindClass(env, c_name);
|
||||
free(c_name);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user