Path: blob/master/test/jdk/build/AbsPathsInImage.java
41140 views
/*1* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.IOException;24import java.io.InputStream;25import java.nio.file.FileVisitResult;26import java.nio.file.Files;27import java.nio.file.Path;28import java.nio.file.Paths;29import java.nio.file.SimpleFileVisitor;30import java.nio.file.attribute.BasicFileAttributes;31import java.util.ArrayList;32import java.util.List;33import java.util.Properties;34import java.util.stream.Collectors;35import java.util.zip.ZipEntry;36import java.util.zip.ZipInputStream;3738/*39* @test40* @bug 822634641* @summary Check all output files for absolute path fragments42* @requires !vm.debug43* @run main AbsPathsInImage44*/45public class AbsPathsInImage {4647// Set this property on command line to scan an alternate dir or file:48// JTREG=JAVA_OPTIONS=-Djdk.test.build.AbsPathInImage.dir=/path/to/dir49public static final String DIR_PROPERTY = "jdk.test.build.AbsPathsInImage.dir";50private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("windows");5152private boolean matchFound = false;5354public static void main(String[] args) throws Exception {55String jdkPathString = System.getProperty("test.jdk");56Path jdkHome = Paths.get(jdkPathString);5758Path dirToScan = jdkHome;59String overrideDir = System.getProperty(DIR_PROPERTY);60if (overrideDir != null) {61dirToScan = Paths.get(overrideDir);62}6364String buildWorkspaceRoot = null;65String buildOutputRoot = null;66String testImageDirString = System.getenv("TEST_IMAGE_DIR");67if (testImageDirString != null) {68Path testImageDir = Paths.get(testImageDirString);69Path buildInfoPropertiesFile = testImageDir.resolve("build-info.properties");70System.out.println("Getting patterns from " + buildInfoPropertiesFile.toString());71Properties buildInfoProperties = new Properties();72try (InputStream inStream = Files.newInputStream(buildInfoPropertiesFile)) {73buildInfoProperties.load(inStream);74}75buildWorkspaceRoot = buildInfoProperties.getProperty("build.workspace.root");76buildOutputRoot = buildInfoProperties.getProperty("build.output.root");77} else {78System.out.println("Getting patterns from local environment");79// Try to resolve the workspace root based on the jtreg test root dir80String testRootDirString = System.getProperty("test.root");81if (testRootDirString != null) {82Path testRootDir = Paths.get(testRootDirString);83// Remove /test/jdk suffix84buildWorkspaceRoot = testRootDir.getParent().getParent().toString();85}86// Remove /jdk87Path buildOutputRootPath = jdkHome.getParent();88if (buildOutputRootPath.endsWith("images")) {89buildOutputRootPath = buildOutputRootPath.getParent();90}91buildOutputRoot = buildOutputRootPath.toString();92}93if (buildWorkspaceRoot == null) {94throw new Error("Could not find workspace root, test cannot run");95}96if (buildOutputRoot == null) {97throw new Error("Could not find build output root, test cannot run");98}99100List<byte[]> searchPatterns = new ArrayList<>();101expandPatterns(searchPatterns, buildWorkspaceRoot);102expandPatterns(searchPatterns, buildOutputRoot);103104System.out.println("Looking for:");105for (byte[] searchPattern : searchPatterns) {106System.out.println(new String(searchPattern));107}108System.out.println();109110AbsPathsInImage absPathsInImage = new AbsPathsInImage();111absPathsInImage.scanFiles(dirToScan, searchPatterns);112113if (absPathsInImage.matchFound) {114throw new Exception("Test failed");115}116}117118/**119* Add path pattern to list of patterns to search for. Create all possible120* variants depending on platform.121*/122private static void expandPatterns(List<byte[]> searchPatterns, String pattern) {123if (IS_WINDOWS) {124String forward = pattern.replace('\\', '/');125String back = pattern.replace('/', '\\');126if (pattern.charAt(1) == ':') {127String forwardUpper = String.valueOf(pattern.charAt(0)).toUpperCase() + forward.substring(1);128String forwardLower = String.valueOf(pattern.charAt(0)).toLowerCase() + forward.substring(1);129String backUpper = String.valueOf(pattern.charAt(0)).toUpperCase() + back.substring(1);130String backLower = String.valueOf(pattern.charAt(0)).toLowerCase() + back.substring(1);131searchPatterns.add(forwardUpper.getBytes());132searchPatterns.add(forwardLower.getBytes());133searchPatterns.add(backUpper.getBytes());134searchPatterns.add(backLower.getBytes());135} else {136searchPatterns.add(forward.getBytes());137searchPatterns.add(back.getBytes());138}139} else {140searchPatterns.add(pattern.getBytes());141}142}143144private void scanFiles(Path root, List<byte[]> searchPatterns) throws IOException {145Files.walkFileTree(root, new SimpleFileVisitor<>() {146@Override147public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {148String fileName = file.toString();149if (Files.isSymbolicLink(file)) {150return super.visitFile(file, attrs);151} else if (fileName.endsWith(".debuginfo") || fileName.endsWith(".pdb")) {152// Do nothing153} else if (fileName.endsWith(".zip")) {154scanZipFile(file, searchPatterns);155} else {156scanFile(file, searchPatterns);157}158return super.visitFile(file, attrs);159}160});161}162163private void scanFile(Path file, List<byte[]> searchPatterns) throws IOException {164List<String> matches = scanBytes(Files.readAllBytes(file), searchPatterns);165if (matches.size() > 0) {166matchFound = true;167System.out.println(file + ":");168for (String match : matches) {169System.out.println(match);170}171System.out.println();172}173}174175private void scanZipFile(Path zipFile, List<byte[]> searchPatterns) throws IOException {176try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {177ZipEntry zipEntry;178while ((zipEntry = zipInputStream.getNextEntry()) != null) {179List<String> matches = scanBytes(zipInputStream.readAllBytes(), searchPatterns);180if (matches.size() > 0) {181matchFound = true;182System.out.println(zipFile + ", " + zipEntry.getName() + ":");183for (String match : matches) {184System.out.println(match);185}186System.out.println();187}188}189}190}191192private List<String> scanBytes(byte[] data, List<byte[]> searchPatterns) {193List<String> matches = new ArrayList<>();194for (int i = 0; i < data.length; i++) {195for (byte[] searchPattern : searchPatterns) {196boolean found = true;197for (int j = 0; j < searchPattern.length; j++) {198if ((i + j >= data.length || data[i + j] != searchPattern[j])) {199found = false;200break;201}202}203if (found) {204matches.add(new String(data, charsStart(data, i), charsOffset(data, i, searchPattern.length)));205// No need to search the same string for multiple patterns206break;207}208}209}210return matches;211}212213private int charsStart(byte[] data, int startIndex) {214int index = startIndex;215while (--index > 0) {216byte datum = data[index];217if (datum < 32 || datum > 126) {218break;219}220}221return index + 1;222}223224private int charsOffset(byte[] data, int startIndex, int startOffset) {225int offset = startOffset;226while (startIndex + ++offset < data.length) {227byte datum = data[startIndex + offset];228if (datum < 32 || datum > 126) {229break;230}231}232return offset;233}234}235236237