< prev index next >

src/share/vm/classfile/classFileParser.cpp

Print this page


   1 /*
   2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


3035       "inner_class_info_index %u has bad constant type in class file %s",
3036       inner_class_info_index, CHECK_0);
3037     // Outer class index
3038     const u2 outer_class_info_index = cfs->get_u2_fast();
3039     check_property(
3040       outer_class_info_index == 0 ||
3041         valid_klass_reference_at(outer_class_info_index),
3042       "outer_class_info_index %u has bad constant type in class file %s",
3043       outer_class_info_index, CHECK_0);
3044     // Inner class name
3045     const u2 inner_name_index = cfs->get_u2_fast();
3046     check_property(
3047       inner_name_index == 0 || valid_symbol_at(inner_name_index),
3048       "inner_name_index %u has bad constant type in class file %s",
3049       inner_name_index, CHECK_0);
3050     if (_need_verify) {
3051       guarantee_property(inner_class_info_index != outer_class_info_index,
3052                          "Class is both outer and inner class in class file %s", CHECK_0);
3053     }
3054     // Access flags
3055     jint flags = cfs->get_u2_fast() & RECOGNIZED_INNER_CLASS_MODIFIERS;














3056     if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
3057       // Set abstract bit for old class files for backward compatibility
3058       flags |= JVM_ACC_ABSTRACT;
3059     }
3060     verify_legal_class_modifiers(flags, CHECK_0);
3061     AccessFlags inner_access_flags(flags);
3062 
3063     inner_classes->at_put(index++, inner_class_info_index);
3064     inner_classes->at_put(index++, outer_class_info_index);
3065     inner_classes->at_put(index++, inner_name_index);
3066     inner_classes->at_put(index++, inner_access_flags.as_short());
3067   }
3068 
3069   // 4347400: make sure there's no duplicate entry in the classes array
3070   if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
3071     for(int i = 0; i < length * 4; i += 4) {
3072       for(int j = i + 4; j < length * 4; j += 4) {
3073         guarantee_property((inner_classes->at(i)   != inner_classes->at(j) ||
3074                             inner_classes->at(i+1) != inner_classes->at(j+1) ||
3075                             inner_classes->at(i+2) != inner_classes->at(j+2) ||


4515         "Illegal static method %s in interface %s",
4516         m->name()->as_C_string(),
4517         this_klass->external_name()
4518       );
4519       return;
4520     }
4521   }
4522 }
4523 
4524 // utility methods for format checking
4525 
4526 void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) const {
4527   if (!_need_verify) { return; }
4528 
4529   const bool is_interface  = (flags & JVM_ACC_INTERFACE)  != 0;
4530   const bool is_abstract   = (flags & JVM_ACC_ABSTRACT)   != 0;
4531   const bool is_final      = (flags & JVM_ACC_FINAL)      != 0;
4532   const bool is_super      = (flags & JVM_ACC_SUPER)      != 0;
4533   const bool is_enum       = (flags & JVM_ACC_ENUM)       != 0;
4534   const bool is_annotation = (flags & JVM_ACC_ANNOTATION) != 0;
4535   const bool is_module_info= (flags & JVM_ACC_MODULE)     != 0;
4536   const bool major_gte_15  = _major_version >= JAVA_1_5_VERSION;
4537 

4538   if ((is_abstract && is_final) ||
4539       (is_interface && !is_abstract) ||
4540       (is_interface && major_gte_15 && (is_super || is_enum)) ||
4541       (!is_interface && major_gte_15 && is_annotation) ||
4542       is_module_info) {
4543     ResourceMark rm(THREAD);
4544     Exceptions::fthrow(
4545       THREAD_AND_LOCATION,
4546       vmSymbols::java_lang_ClassFormatError(),
4547       "Illegal class modifiers in class %s: 0x%X",
4548       _class_name->as_C_string(), flags
4549     );
4550     return;
4551   }
4552 }
4553 
4554 static bool has_illegal_visibility(jint flags) {
4555   const bool is_public    = (flags & JVM_ACC_PUBLIC)    != 0;
4556   const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
4557   const bool is_private   = (flags & JVM_ACC_PRIVATE)   != 0;
4558 
4559   return ((is_public && is_protected) ||
4560           (is_public && is_private) ||
4561           (is_protected && is_private));
4562 }


5717   const u2 cp_size = stream->get_u2_fast();
5718 
5719   guarantee_property(
5720     cp_size >= 1, "Illegal constant pool size %u in class file %s",
5721     cp_size, CHECK);
5722 
5723   _cp = ConstantPool::allocate(_loader_data,
5724                                cp_size,
5725                                CHECK);
5726 
5727   ConstantPool* const cp = _cp;
5728 
5729   parse_constant_pool(stream, cp, cp_size, CHECK);
5730 
5731   assert(cp_size == (const u2)cp->length(), "invariant");
5732 
5733   // ACCESS FLAGS
5734   stream->guarantee_more(8, CHECK);  // flags, this_class, super_class, infs_len
5735 
5736   // Access flags
5737   jint flags = stream->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS;














5738 
5739   if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
5740     // Set abstract bit for old class files for backward compatibility
5741     flags |= JVM_ACC_ABSTRACT;
5742   }
5743 
5744   _access_flags.set_flags(flags);
5745 
5746   verify_legal_class_modifiers((jint)_access_flags.as_int(), CHECK);
5747 
5748   // This class and superclass
5749   _this_class_index = stream->get_u2_fast();
5750   check_property(
5751     valid_cp_range(_this_class_index, cp_size) &&
5752       cp->tag_at(_this_class_index).is_unresolved_klass(),
5753     "Invalid this class index %u in constant pool in class file %s",
5754     _this_class_index, CHECK);
5755 
5756   Symbol* const class_name_in_cp = cp->klass_name_at(_this_class_index);
5757   assert(class_name_in_cp != NULL, "class_name can't be null");


   1 /*
   2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


3035       "inner_class_info_index %u has bad constant type in class file %s",
3036       inner_class_info_index, CHECK_0);
3037     // Outer class index
3038     const u2 outer_class_info_index = cfs->get_u2_fast();
3039     check_property(
3040       outer_class_info_index == 0 ||
3041         valid_klass_reference_at(outer_class_info_index),
3042       "outer_class_info_index %u has bad constant type in class file %s",
3043       outer_class_info_index, CHECK_0);
3044     // Inner class name
3045     const u2 inner_name_index = cfs->get_u2_fast();
3046     check_property(
3047       inner_name_index == 0 || valid_symbol_at(inner_name_index),
3048       "inner_name_index %u has bad constant type in class file %s",
3049       inner_name_index, CHECK_0);
3050     if (_need_verify) {
3051       guarantee_property(inner_class_info_index != outer_class_info_index,
3052                          "Class is both outer and inner class in class file %s", CHECK_0);
3053     }
3054     // Access flags
3055     jint flags;
3056     // Don't allow JVM_ACC_MODULE in JDK-9 and later.
3057     if (_major_version >= JAVA_9_VERSION) {
3058       flags = cfs->get_u2_fast() & (RECOGNIZED_INNER_CLASS_MODIFIERS | JVM_ACC_MODULE);
3059       if (flags & JVM_ACC_MODULE) {
3060         ResourceMark rm(THREAD);
3061         Exceptions::fthrow(
3062           THREAD_AND_LOCATION,
3063           vmSymbols::java_lang_NoClassDefFoundError(),
3064           "Illegal ACC_MODULE class modifier in class %s",
3065           _class_name->as_C_string());
3066       }
3067     } else {
3068       flags = cfs->get_u2_fast() & RECOGNIZED_INNER_CLASS_MODIFIERS;
3069     }
3070     if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
3071       // Set abstract bit for old class files for backward compatibility
3072       flags |= JVM_ACC_ABSTRACT;
3073     }
3074     verify_legal_class_modifiers(flags, CHECK_0);
3075     AccessFlags inner_access_flags(flags);
3076 
3077     inner_classes->at_put(index++, inner_class_info_index);
3078     inner_classes->at_put(index++, outer_class_info_index);
3079     inner_classes->at_put(index++, inner_name_index);
3080     inner_classes->at_put(index++, inner_access_flags.as_short());
3081   }
3082 
3083   // 4347400: make sure there's no duplicate entry in the classes array
3084   if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
3085     for(int i = 0; i < length * 4; i += 4) {
3086       for(int j = i + 4; j < length * 4; j += 4) {
3087         guarantee_property((inner_classes->at(i)   != inner_classes->at(j) ||
3088                             inner_classes->at(i+1) != inner_classes->at(j+1) ||
3089                             inner_classes->at(i+2) != inner_classes->at(j+2) ||


4529         "Illegal static method %s in interface %s",
4530         m->name()->as_C_string(),
4531         this_klass->external_name()
4532       );
4533       return;
4534     }
4535   }
4536 }
4537 
4538 // utility methods for format checking
4539 
4540 void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) const {
4541   if (!_need_verify) { return; }
4542 
4543   const bool is_interface  = (flags & JVM_ACC_INTERFACE)  != 0;
4544   const bool is_abstract   = (flags & JVM_ACC_ABSTRACT)   != 0;
4545   const bool is_final      = (flags & JVM_ACC_FINAL)      != 0;
4546   const bool is_super      = (flags & JVM_ACC_SUPER)      != 0;
4547   const bool is_enum       = (flags & JVM_ACC_ENUM)       != 0;
4548   const bool is_annotation = (flags & JVM_ACC_ANNOTATION) != 0;
4549   const bool is_module     = (flags & JVM_ACC_MODULE)     != 0;
4550   const bool major_gte_15  = _major_version >= JAVA_1_5_VERSION;
4551 
4552   assert(!is_module, "JVM_ACC_MODULE should not be set");
4553   if ((is_abstract && is_final) ||
4554       (is_interface && !is_abstract) ||
4555       (is_interface && major_gte_15 && (is_super || is_enum)) ||
4556       (!is_interface && major_gte_15 && is_annotation)) {

4557     ResourceMark rm(THREAD);
4558     Exceptions::fthrow(
4559       THREAD_AND_LOCATION,
4560       vmSymbols::java_lang_ClassFormatError(),
4561       "Illegal class modifiers in class %s: 0x%X",
4562       _class_name->as_C_string(), flags
4563     );
4564     return;
4565   }
4566 }
4567 
4568 static bool has_illegal_visibility(jint flags) {
4569   const bool is_public    = (flags & JVM_ACC_PUBLIC)    != 0;
4570   const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
4571   const bool is_private   = (flags & JVM_ACC_PRIVATE)   != 0;
4572 
4573   return ((is_public && is_protected) ||
4574           (is_public && is_private) ||
4575           (is_protected && is_private));
4576 }


5731   const u2 cp_size = stream->get_u2_fast();
5732 
5733   guarantee_property(
5734     cp_size >= 1, "Illegal constant pool size %u in class file %s",
5735     cp_size, CHECK);
5736 
5737   _cp = ConstantPool::allocate(_loader_data,
5738                                cp_size,
5739                                CHECK);
5740 
5741   ConstantPool* const cp = _cp;
5742 
5743   parse_constant_pool(stream, cp, cp_size, CHECK);
5744 
5745   assert(cp_size == (const u2)cp->length(), "invariant");
5746 
5747   // ACCESS FLAGS
5748   stream->guarantee_more(8, CHECK);  // flags, this_class, super_class, infs_len
5749 
5750   // Access flags
5751   jint flags;
5752   // Don't allow JVM_ACC_MODULE in JDK-9 and later.
5753   if (_major_version >= JAVA_9_VERSION) {
5754     flags = stream->get_u2_fast() & (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_MODULE);
5755     if (flags & JVM_ACC_MODULE) {
5756       ResourceMark rm(THREAD);
5757       Exceptions::fthrow(
5758         THREAD_AND_LOCATION,
5759         vmSymbols::java_lang_NoClassDefFoundError(),
5760         "Illegal ACC_MODULE class modifier in class %s",
5761         _class_name->as_C_string());
5762     }
5763   } else {
5764     flags = stream->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS;
5765   }
5766 
5767   if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
5768     // Set abstract bit for old class files for backward compatibility
5769     flags |= JVM_ACC_ABSTRACT;
5770   }
5771 
5772   _access_flags.set_flags(flags);
5773 
5774   verify_legal_class_modifiers((jint)_access_flags.as_int(), CHECK);
5775 
5776   // This class and superclass
5777   _this_class_index = stream->get_u2_fast();
5778   check_property(
5779     valid_cp_range(_this_class_index, cp_size) &&
5780       cp->tag_at(_this_class_index).is_unresolved_klass(),
5781     "Invalid this class index %u in constant pool in class file %s",
5782     _this_class_index, CHECK);
5783 
5784   Symbol* const class_name_in_cp = cp->klass_name_at(_this_class_index);
5785   assert(class_name_in_cp != NULL, "class_name can't be null");


< prev index next >