Path: blob/master/test/jdk/build/AbsPathsInImage.java
66642 views
/*1* Copyright (c) 2019, 2022, 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.zip.ZipEntry;35import java.util.zip.ZipInputStream;3637/*38* @test39* @bug 822634640* @summary Check all output files for absolute path fragments41* @requires !vm.debug42* @run main AbsPathsInImage43*/44public class AbsPathsInImage {4546// Set this property on command line to scan an alternate dir or file:47// JTREG=JAVA_OPTIONS=-Djdk.test.build.AbsPathInImage.dir=/path/to/dir48public static final String DIR_PROPERTY = "jdk.test.build.AbsPathsInImage.dir";49private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("windows");50private static final boolean IS_LINUX = System.getProperty("os.name").toLowerCase().contains("linux");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}99// Validate the root paths100if (!Paths.get(buildWorkspaceRoot).isAbsolute()) {101throw new Error("Workspace root is not an absolute path: " + buildWorkspaceRoot);102}103if (!Paths.get(buildOutputRoot).isAbsolute()) {104throw new Error("Output root is not an absolute path: " + buildOutputRoot);105}106107List<byte[]> searchPatterns = new ArrayList<>();108expandPatterns(searchPatterns, buildWorkspaceRoot);109expandPatterns(searchPatterns, buildOutputRoot);110111System.out.println("Looking for:");112for (byte[] searchPattern : searchPatterns) {113System.out.println(new String(searchPattern));114}115System.out.println();116117AbsPathsInImage absPathsInImage = new AbsPathsInImage();118absPathsInImage.scanFiles(dirToScan, searchPatterns);119120if (absPathsInImage.matchFound) {121throw new Exception("Test failed");122}123}124125/**126* Add path pattern to list of patterns to search for. Create all possible127* variants depending on platform.128*/129private static void expandPatterns(List<byte[]> searchPatterns, String pattern) {130if (IS_WINDOWS) {131String forward = pattern.replace('\\', '/');132String back = pattern.replace('/', '\\');133if (pattern.charAt(1) == ':') {134String forwardUpper = String.valueOf(pattern.charAt(0)).toUpperCase() + forward.substring(1);135String forwardLower = String.valueOf(pattern.charAt(0)).toLowerCase() + forward.substring(1);136String backUpper = String.valueOf(pattern.charAt(0)).toUpperCase() + back.substring(1);137String backLower = String.valueOf(pattern.charAt(0)).toLowerCase() + back.substring(1);138searchPatterns.add(forwardUpper.getBytes());139searchPatterns.add(forwardLower.getBytes());140searchPatterns.add(backUpper.getBytes());141searchPatterns.add(backLower.getBytes());142} else {143searchPatterns.add(forward.getBytes());144searchPatterns.add(back.getBytes());145}146} else {147searchPatterns.add(pattern.getBytes());148}149}150151private void scanFiles(Path root, List<byte[]> searchPatterns) throws IOException {152Files.walkFileTree(root, new SimpleFileVisitor<>() {153@Override154public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {155String dirName = dir.toString();156if (dirName.endsWith(".dSYM")) {157return FileVisitResult.SKIP_SUBTREE;158}159return super.preVisitDirectory(dir, attrs);160}161162@Override163public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {164String fileName = file.toString();165if (Files.isSymbolicLink(file)) {166return super.visitFile(file, attrs);167} else if ((fileName.endsWith(".debuginfo") && !IS_LINUX) || fileName.endsWith(".pdb")) {168// Do nothing169} else if (fileName.endsWith(".zip")) {170scanZipFile(file, searchPatterns);171} else {172scanFile(file, searchPatterns);173}174return super.visitFile(file, attrs);175}176});177}178179private void scanFile(Path file, List<byte[]> searchPatterns) throws IOException {180List<String> matches = scanBytes(Files.readAllBytes(file), searchPatterns);181if (matches.size() > 0) {182matchFound = true;183System.out.println(file + ":");184for (String match : matches) {185System.out.println(match);186}187System.out.println();188}189}190191private void scanZipFile(Path zipFile, List<byte[]> searchPatterns) throws IOException {192try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile))) {193ZipEntry zipEntry;194while ((zipEntry = zipInputStream.getNextEntry()) != null) {195List<String> matches = scanBytes(zipInputStream.readAllBytes(), searchPatterns);196if (matches.size() > 0) {197matchFound = true;198System.out.println(zipFile + ", " + zipEntry.getName() + ":");199for (String match : matches) {200System.out.println(match);201}202System.out.println();203}204}205}206}207208private List<String> scanBytes(byte[] data, List<byte[]> searchPatterns) {209List<String> matches = new ArrayList<>();210for (int i = 0; i < data.length; i++) {211for (byte[] searchPattern : searchPatterns) {212boolean found = true;213for (int j = 0; j < searchPattern.length; j++) {214if ((i + j >= data.length || data[i + j] != searchPattern[j])) {215found = false;216break;217}218}219if (found) {220matches.add(new String(data, charsStart(data, i), charsOffset(data, i, searchPattern.length)));221// No need to search the same string for multiple patterns222break;223}224}225}226return matches;227}228229private int charsStart(byte[] data, int startIndex) {230int index = startIndex;231while (--index > 0) {232byte datum = data[index];233if (datum < 32 || datum > 126) {234break;235}236}237return index + 1;238}239240private int charsOffset(byte[] data, int startIndex, int startOffset) {241int offset = startOffset;242while (startIndex + ++offset < data.length) {243byte datum = data[startIndex + offset];244if (datum < 32 || datum > 126) {245break;246}247}248return offset;249}250}251252253