# HG changeset patch # User jlahoda # Date 1565684854 -7200 # Node ID ffc34eaf7b49d2c0bf84140dd39dd7b96093ed08 # Parent 447d48371b41628eb44dde180b16e679104c4af2 8228502: javac crashed on a broken classfile with ConstantValue attribute on a field of type Object Summary: Produce an error when reading a classfile with a field with ConstantValue with a wrong type. Reviewed-by: vromero diff -r 447d48371b41 -r ffc34eaf7b49 src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Aug 13 10:27:33 2019 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Aug 13 10:27:34 2019 +0200 @@ -808,8 +808,11 @@ checkType(var, Double.class, v); break; case CLASS: - Assert.check(var.type.tsym == syms.stringType.tsym); - checkType(var, String.class, v); + if (var.type.tsym == syms.stringType.tsym) { + checkType(var, String.class, v); + } else { + throw badClassFile("bad.constant.value.type", var.type); + } break; default: // ignore ConstantValue attribute if type is not primitive or String diff -r 447d48371b41 -r ffc34eaf7b49 src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Aug 13 10:27:33 2019 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Aug 13 10:27:34 2019 +0200 @@ -2281,6 +2281,10 @@ compiler.misc.bad.constant.value=\ bad constant value ''{0}'' for {1}, expected {2} +# 0: type (field type) +compiler.misc.bad.constant.value.type=\ + variable of type ''{0}'' cannot have a constant value, but has one specified + # 0: string (classfile major version), 1: string (classfile minor version) compiler.misc.invalid.default.interface=\ default method found in version {0}.{1} classfile diff -r 447d48371b41 -r ffc34eaf7b49 test/langtools/tools/javac/classfiles/attributes/ConstantValue/BrokenConstantValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/classfiles/attributes/ConstantValue/BrokenConstantValue.java Tue Aug 13 10:27:34 2019 +0200 @@ -0,0 +1,9 @@ +/* @test /nodynamiccopyright/ + * @compile HasBrokenConstantValue.jcod + * @compile/fail/ref=BrokenConstantValue.out -XDrawDiagnostics BrokenConstantValue.java + */ +public class BrokenConstantValue { + void t() { + String s = HasBrokenConstantValue.VALUE; + } +} diff -r 447d48371b41 -r ffc34eaf7b49 test/langtools/tools/javac/classfiles/attributes/ConstantValue/BrokenConstantValue.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/classfiles/attributes/ConstantValue/BrokenConstantValue.out Tue Aug 13 10:27:34 2019 +0200 @@ -0,0 +1,2 @@ +BrokenConstantValue.java:7:21: compiler.err.cant.access: HasBrokenConstantValue, (compiler.misc.bad.class.file.header: HasBrokenConstantValue.class, (compiler.misc.bad.constant.value.type: java.lang.Object)) +1 error diff -r 447d48371b41 -r ffc34eaf7b49 test/langtools/tools/javac/classfiles/attributes/ConstantValue/HasBrokenConstantValue.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/classfiles/attributes/ConstantValue/HasBrokenConstantValue.jcod Tue Aug 13 10:27:34 2019 +0200 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// ConstantValue attribute on a field that has wrong type (j.l.Object): + +class HasBrokenConstantValue { + 0xCAFEBABE; + 0; // minor version + 55; // version + [] { // Constant Pool + ; // first element is empty + Method #3 #14; // #1 + class #15; // #2 + class #16; // #3 + Utf8 "VALUE"; // #4 + Utf8 "Ljava/lang/Object;"; // #5 + Utf8 "ConstantValue"; // #6 + String #17; // #7 + Utf8 ""; // #8 + Utf8 "()V"; // #9 + Utf8 "Code"; // #10 + Utf8 "LineNumberTable"; // #11 + Utf8 "SourceFile"; // #12 + Utf8 "HasBrokenConstantValue.java"; // #13 + NameAndType #8 #9; // #14 + Utf8 "HasBrokenConstantValue"; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 ""; // #17 + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + { // Member + 0x0019; // access + #4; // name_cpx + #5; // sig_cpx + [] { // Attributes + Attr(#6) { // ConstantValue + #7; + } // end ConstantValue + } // Attributes + } // Member + } // fields + + [] { // methods + { // Member + 0x0001; // access + #8; // name_cpx + #9; // sig_cpx + [] { // Attributes + Attr(#10) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#11) { // LineNumberTable + [] { // LineNumberTable + 0 1; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#12) { // SourceFile + #13; + } // end SourceFile + } // Attributes +} // end class HasBrokenConstantValue diff -r 447d48371b41 -r ffc34eaf7b49 test/langtools/tools/javac/diags/examples/BadConstantValueType/BadConstantValueType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/diags/examples/BadConstantValueType/BadConstantValueType.java Tue Aug 13 10:27:34 2019 +0200 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.misc.bad.constant.value.type +// key: compiler.misc.bad.class.file.header +// key: compiler.err.cant.access +// options: -processor CreateBadClassFile +// run: exec --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED + +/* The annotation processor will create an invalid classfile with a static + * final field of type java.lang.Object having ConstantValue attribute with + * a String value + */ +class BadConstantValueType { + private static final String C = Test.test; +} diff -r 447d48371b41 -r ffc34eaf7b49 test/langtools/tools/javac/diags/examples/BadConstantValueType/processors/CreateBadClassFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/diags/examples/BadConstantValueType/processors/CreateBadClassFile.java Tue Aug 13 10:27:34 2019 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2013, 2019, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.tools.*; + +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info; +import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info; +import com.sun.tools.classfile.ConstantPool.CPInfo; + +/* Create an invalid classfile with a static final field of type object with + * ConstantValue of type String. + */ +@SupportedAnnotationTypes("*") +public class CreateBadClassFile extends AbstractProcessor { + public boolean process(Set elems, RoundEnvironment renv) { + if (++round == 1) { + ConstantPool cp = new ConstantPool(new CPInfo[] { + new CONSTANT_Utf8_info(""), //0 + new CONSTANT_Utf8_info("Test"), //1 + new CONSTANT_Class_info(null, 1), //2 + new CONSTANT_Utf8_info("java/lang/Object"), //3 + new CONSTANT_Class_info(null, 3), //4 + new CONSTANT_Utf8_info("test"), //5 + new CONSTANT_Utf8_info("Ljava/lang/Object;"), //6 + new CONSTANT_Utf8_info("ConstantValue"), //7 + }); + ClassFile cf = new ClassFile(0xCAFEBABE, + 0, + 51, + cp, + new AccessFlags(AccessFlags.ACC_ABSTRACT | + AccessFlags.ACC_INTERFACE | + AccessFlags.ACC_PUBLIC), + 2, + 4, + new int[0], + new Field[] { + new Field(new AccessFlags(AccessFlags.ACC_PUBLIC | + AccessFlags.ACC_STATIC | + AccessFlags.ACC_FINAL), + 5, + new Descriptor(6), + new Attributes(cp, new Attribute[] { + new ConstantValue_attribute(7, 6) + })) + }, + new Method[0], + new Attributes(cp, new Attribute[0])); + try { + JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test"); + try (OutputStream out = clazz.openOutputStream()) { + new ClassWriter().write(cf, out); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + return false; + } + + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + int round = 0; +}