mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8228502: javac crashed on a broken classfile with ConstantValue attribute on a field of type Object
Produce an error when reading a classfile with a field with ConstantValue with a wrong type. Reviewed-by: vromero
This commit is contained in:
parent
36ae680f2a
commit
f033152eae
7 changed files with 250 additions and 2 deletions
|
@ -808,8 +808,11 @@ public class ClassReader {
|
||||||
checkType(var, Double.class, v);
|
checkType(var, Double.class, v);
|
||||||
break;
|
break;
|
||||||
case CLASS:
|
case CLASS:
|
||||||
Assert.check(var.type.tsym == syms.stringType.tsym);
|
if (var.type.tsym == syms.stringType.tsym) {
|
||||||
checkType(var, String.class, v);
|
checkType(var, String.class, v);
|
||||||
|
} else {
|
||||||
|
throw badClassFile("bad.constant.value.type", var.type);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// ignore ConstantValue attribute if type is not primitive or String
|
// ignore ConstantValue attribute if type is not primitive or String
|
||||||
|
|
|
@ -2281,6 +2281,10 @@ compiler.misc.bad.constant.range=\
|
||||||
compiler.misc.bad.constant.value=\
|
compiler.misc.bad.constant.value=\
|
||||||
bad constant value ''{0}'' for {1}, expected {2}
|
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)
|
# 0: string (classfile major version), 1: string (classfile minor version)
|
||||||
compiler.misc.invalid.default.interface=\
|
compiler.misc.invalid.default.interface=\
|
||||||
default method found in version {0}.{1} classfile
|
default method found in version {0}.{1} classfile
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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 "<init>"; // #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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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<? extends TypeElement> 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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue