Tue, 07 Jul 2020 10:30:39 -0700
8245412: Better class definitions
Reviewed-by: mbalao, andrew
Contributed-by: Ekaterina Vergizova <katya@azul.com>
src/share/vm/classfile/systemDictionary.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/classfile/systemDictionary.cpp Fri Oct 16 23:17:14 2020 +0100 1.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Tue Jul 07 10:30:39 2020 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -1074,6 +1074,18 @@ 1.11 return k(); 1.12 } 1.13 1.14 +static bool is_prohibited_package_slow(Symbol* class_name) { 1.15 + // Caller has ResourceMark 1.16 + int length; 1.17 + jchar* unicode = class_name->as_unicode(length); 1.18 + return (length >= 5 && 1.19 + unicode[0] == 'j' && 1.20 + unicode[1] == 'a' && 1.21 + unicode[2] == 'v' && 1.22 + unicode[3] == 'a' && 1.23 + unicode[4] == '/'); 1.24 +} 1.25 + 1.26 // Add a klass to the system from a stream (called by jni_DefineClass and 1.27 // JVM_DefineClass). 1.28 // Note: class_name can be NULL. In that case we do not know the name of 1.29 @@ -1121,24 +1133,33 @@ 1.30 if (!HAS_PENDING_EXCEPTION && 1.31 !class_loader.is_null() && 1.32 parsed_name != NULL && 1.33 - parsed_name->utf8_length() >= (int)pkglen && 1.34 - !strncmp((const char*)parsed_name->bytes(), pkg, pkglen)) { 1.35 - // It is illegal to define classes in the "java." package from 1.36 - // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader 1.37 + parsed_name->utf8_length() >= (int)pkglen) { 1.38 ResourceMark rm(THREAD); 1.39 - char* name = parsed_name->as_C_string(); 1.40 - char* index = strrchr(name, '/'); 1.41 - assert(index != NULL, "must be"); 1.42 - *index = '\0'; // chop to just the package name 1.43 - while ((index = strchr(name, '/')) != NULL) { 1.44 - *index = '.'; // replace '/' with '.' in package name 1.45 + bool prohibited; 1.46 + const jbyte* base = parsed_name->base(); 1.47 + if ((base[0] | base[1] | base[2] | base[3] | base[4]) & 0x80) { 1.48 + prohibited = is_prohibited_package_slow(parsed_name); 1.49 + } else { 1.50 + char* name = parsed_name->as_C_string(); 1.51 + prohibited = (strncmp(name, pkg, pkglen) == 0); 1.52 } 1.53 - const char* fmt = "Prohibited package name: %s"; 1.54 - size_t len = strlen(fmt) + strlen(name); 1.55 - char* message = NEW_RESOURCE_ARRAY(char, len); 1.56 - jio_snprintf(message, len, fmt, name); 1.57 - Exceptions::_throw_msg(THREAD_AND_LOCATION, 1.58 - vmSymbols::java_lang_SecurityException(), message); 1.59 + if (prohibited) { 1.60 + // It is illegal to define classes in the "java." package from 1.61 + // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader 1.62 + char* name = parsed_name->as_C_string(); 1.63 + char* index = strrchr(name, '/'); 1.64 + assert(index != NULL, "must be"); 1.65 + *index = '\0'; // chop to just the package name 1.66 + while ((index = strchr(name, '/')) != NULL) { 1.67 + *index = '.'; // replace '/' with '.' in package name 1.68 + } 1.69 + const char* fmt = "Prohibited package name: %s"; 1.70 + size_t len = strlen(fmt) + strlen(name); 1.71 + char* message = NEW_RESOURCE_ARRAY(char, len); 1.72 + jio_snprintf(message, len, fmt, name); 1.73 + Exceptions::_throw_msg(THREAD_AND_LOCATION, 1.74 + vmSymbols::java_lang_SecurityException(), message); 1.75 + } 1.76 } 1.77 1.78 if (!HAS_PENDING_EXCEPTION) {