undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
186
test/langtools/tools/javac/classfiles/ClassVersionChecker.java
Normal file
186
test/langtools/tools/javac/classfiles/ClassVersionChecker.java
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7157626 8001112 8188870 8173382 8193290 8205619 8245586 8257453 8306586 8330184
|
||||
* 8342983 8355751 8370894
|
||||
* @summary Test major version for all legal combinations for -source and -target
|
||||
* @author sgoel
|
||||
*
|
||||
* @modules jdk.compiler
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
/*
|
||||
* If not explicitly specified the latest source and latest target
|
||||
* values are the defaults. If explicitly specified, the target value
|
||||
* has to be greater than or equal to the source value.
|
||||
*/
|
||||
public class ClassVersionChecker {
|
||||
private static enum Version {
|
||||
EIGHT("8", 52),
|
||||
NINE("9", 53),
|
||||
TEN("10", 54),
|
||||
ELEVEN("11", 55),
|
||||
TWELVE("12", 56),
|
||||
THIRTEEN("13", 57),
|
||||
FOURTEEN("14", 58),
|
||||
FIFTEEN("15", 59),
|
||||
SIXTEEN("16", 60),
|
||||
SEVENTEEN("17", 61),
|
||||
EIGHTEEN("18", 62),
|
||||
NINETEEN("19", 63),
|
||||
TWENTY("20", 64),
|
||||
TWENTY_ONE("21", 65),
|
||||
TWENTY_TWO("22", 66),
|
||||
TWENTY_THREE("23", 67),
|
||||
TWENTY_FOUR("24", 68),
|
||||
TWENTY_FIVE("25", 69),
|
||||
TWENTY_SIX("26", 70),
|
||||
TWENTY_SEVEN("27", 71),
|
||||
; // Reduce code churn when appending new constants
|
||||
|
||||
private Version(String release, int classFileVer) {
|
||||
this.release = release;
|
||||
this.classFileVer = classFileVer;
|
||||
}
|
||||
private final String release;
|
||||
private final int classFileVer;
|
||||
|
||||
String release() {return release;}
|
||||
int classFileVer() {return classFileVer;}
|
||||
}
|
||||
|
||||
static final Version CURRENT;
|
||||
static {
|
||||
Version[] versions = Version.values();
|
||||
int index = versions.length;
|
||||
CURRENT = versions[index - 1];
|
||||
}
|
||||
|
||||
int errors;
|
||||
|
||||
File javaFile = null;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
new ClassVersionChecker().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
writeTestFile();
|
||||
/*
|
||||
* Rules applicable for -source and -target combinations:
|
||||
* 1. If both empty, version num is for the current release
|
||||
* 2. If source is not empty and target is empty, version is
|
||||
* based on the current release
|
||||
* 3. If both non-empty, version is based on target
|
||||
*/
|
||||
test("", "", CURRENT.classFileVer());
|
||||
for (Version source : Version.values()) {
|
||||
test(source.release(), "", CURRENT.classFileVer()); // no target
|
||||
for (Version target : Version.values()) {
|
||||
if (target.compareTo(source) < 0)
|
||||
continue; // Target < source not a valid set of arguments
|
||||
else {
|
||||
logMsg("Running for src = " + source + " target = "+ target +
|
||||
" expected = " + target.classFileVer());
|
||||
test(source.release(), target.release(), target.classFileVer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors found");
|
||||
}
|
||||
|
||||
void test(String i, String j, int expected) {
|
||||
File classFile = compileTestFile(i, j, javaFile);
|
||||
short majorVer = getMajorVersion(classFile);
|
||||
checkVersion(majorVer, expected);
|
||||
}
|
||||
|
||||
void writeTestFile() throws IOException {
|
||||
javaFile = new File("Test.java");
|
||||
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(javaFile)));) {
|
||||
out.println("class Test { ");
|
||||
out.println(" public void foo() { }");
|
||||
out.println("}");
|
||||
} catch (IOException ioe) {
|
||||
error("IOException while creating Test.java" + ioe);
|
||||
}
|
||||
}
|
||||
|
||||
File compileTestFile(String i, String j, File f) {
|
||||
int rc = -1;
|
||||
// Src and target are empty
|
||||
if (i.isEmpty() && j.isEmpty() ) {
|
||||
rc = compile("-g", f.getPath());
|
||||
} else if( j.isEmpty()) { // target is empty
|
||||
rc = compile("-source", i, "-g", f.getPath());
|
||||
} else {
|
||||
rc = compile("-source", i, "-target", j, "-g", f.getPath());
|
||||
}
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
int compile(String... args) {
|
||||
return com.sun.tools.javac.Main.compile(args);
|
||||
}
|
||||
|
||||
void logMsg (String str) {
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
short getMajorVersion(File f) {
|
||||
List<String> args = new ArrayList<String>();
|
||||
short majorVer = 0;
|
||||
try(DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));) {
|
||||
in.readInt();
|
||||
in.readShort();
|
||||
majorVer = in.readShort();
|
||||
System.out.println("major version:" + majorVer);
|
||||
} catch (IOException e) {
|
||||
error("IOException while reading Test.class" + e);
|
||||
}
|
||||
return majorVer;
|
||||
}
|
||||
|
||||
void checkVersion(short majorVer, int expected) {
|
||||
if (majorVer != expected ) {
|
||||
error("versions did not match, Expected: " + expected + "Got: " + majorVer);
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.out.println("error: " + msg);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue