7016187: javac -h could generate conflict .h for inner class and class name with '_'

Reviewed-by: vromero
This commit is contained in:
Archie L. Cobbs 2023-03-18 17:32:00 +00:00 committed by Vicente Romero
parent 033c0b17cb
commit e339e183c1
2 changed files with 42 additions and 4 deletions

View File

@ -29,6 +29,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import javax.tools.FileObject;
@ -84,6 +85,12 @@ public class JNIWriter {
*/
private boolean checkAll;
/**
* Mapping from output file name to class name, for all classes we've written.
* This is used to detect when two classes generate the same output file.
*/
private final HashMap<String, String> filesWritten = new HashMap<>();
/**
* If true, class files will be written in module-specific subdirectories
* of the NATIVE_HEADER_OUTPUT location.
@ -183,9 +190,14 @@ public class JNIWriter {
} else {
outLocn = StandardLocation.NATIVE_HEADER_OUTPUT;
}
FileObject outFile
= fileManager.getFileForOutput(outLocn,
"", className.replaceAll("[.$]", "_") + ".h", null);
String fileName = className.replaceAll("[.$]", "_") + ".h";
String prevName = filesWritten.put(fileName, className);
if (prevName != null) {
throw new IOException(String.format(
"native header file collision between %s and %s (both generate %s)",
prevName, className, fileName));
}
FileObject outFile = fileManager.getFileForOutput(outLocn, "", fileName, null);
PrintWriter out = new PrintWriter(outFile.openWriter());
try {
write(out, c);

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 7150368 8003412 8000407
* @bug 7150368 8003412 8000407 7016187
* @summary javac should include basic ability to generate native headers
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
@ -149,6 +149,32 @@ public class NativeHeaderTest {
test(rk, gk, files, expect);
}
@Test
void conflictTest(RunKind rk, GenKind gk) throws Exception {
// These two classes will generate the same header file "Foo_Bar.h"
List<File> files = new ArrayList<File>();
files.add(createFile("p/Foo.java", """
public class Foo {
public static class Bar {
public static native void method1();
}
}
"""));
files.add(createFile("p/Foo_Bar.java", """
public class Foo_Bar {
public static native void method2();
}
"""));
try {
test(rk, gk, files, null);
throw new AssertionError("expected failure");
} catch (Exception e) {
// expected
}
}
/**
* The worker method for each test case.
* Compile the files and verify that exactly the expected set of header files