src/share/classes/org/openjdk/jigsaw/ModuleFile.java

Print this page

        

*** 60,69 **** --- 60,72 ---- private DataInputStream stream; private File destination; private boolean deflate; private HashType hashtype; + private File natlibs; + private File natcmds; + private File configs; private static class CountingInputStream extends FilterInputStream { int count; public CountingInputStream(InputStream stream, int count) { super(stream);
*** 178,193 **** } } public void readRest() throws IOException { extract = false; ! readRest(null, false); } public void readRest(File dst, boolean deflate) throws IOException { ! this.destination = dst; this.deflate = deflate; try { if (extract) Files.store(moduleInfoBytes, computeRealPath("info")); // Module-Info and Signature, if present, have been consumed --- 181,206 ---- } } public void readRest() throws IOException { extract = false; ! readRest(null, false, null, null, null); } public void readRest(File dst, boolean deflate) throws IOException { ! readRest(dst, deflate, null, null, null); ! } ! ! public void readRest(File dst, boolean deflate, File natlibs, ! File natcmds, File configs) ! throws IOException ! { ! this.destination = dst.getCanonicalFile(); this.deflate = deflate; + this.natlibs = natlibs != null ? natlibs : new File(destination, "lib"); + this.natcmds = natcmds != null ? natcmds : new File(destination, "bin"); + this.configs = configs != null ? configs : new File(destination, "etc"); try { if (extract) Files.store(moduleInfoBytes, computeRealPath("info")); // Module-Info and Signature, if present, have been consumed
*** 258,267 **** --- 271,281 ---- return contentStream; } public void close() throws IOException { try { + try { if (contentStream != null) { contentStream.close(); contentStream = null; } } finally {
*** 268,279 **** --- 282,300 ---- if (fileIn != null) { fileIn.close(); fileIn = null; } } + } finally { + if (filesWriter != null) { + filesWriter.close(); + filesWriter = null; } + } + } + public void readModule() throws IOException { extract = false; readStart(); readRest(); }
*** 428,438 **** OutputStream out = openOutputStream(type, header.getPath())) { copyStream(gin, out); } if (extract) ! markNativeCodeExecutable(type, currentPath); } public void readUncompressedFile(DataInputStream in, SectionType type, int csize) --- 449,459 ---- OutputStream out = openOutputStream(type, header.getPath())) { copyStream(gin, out); } if (extract) ! postExtract(type, currentPath); } public void readUncompressedFile(DataInputStream in, SectionType type, int csize)
*** 446,457 **** byte[] buf = new byte[8192]; int n; while ((n = cin.read(buf)) >= 0) out.write(buf, 0, n); } ! markNativeCodeExecutable(type, currentPath); } public byte[] readModuleInfo(DataInputStream in, int csize) throws IOException { CountingInputStream cin = new CountingInputStream(in, csize); --- 467,480 ---- byte[] buf = new byte[8192]; int n; while ((n = cin.read(buf)) >= 0) out.write(buf, 0, n); } ! if (extract) { ! postExtract(type, currentPath); } + } public byte[] readModuleInfo(DataInputStream in, int csize) throws IOException { CountingInputStream cin = new CountingInputStream(in, csize);
*** 467,498 **** throws IOException { return readModuleInfo(in, csize); // signature has the same format } ! private File computeRealPath(String storedpath) throws IOException { ! String convertedpath = storedpath.replace('/', File.separatorChar); ! File path = new File(convertedpath); ! // Absolute path names are not permitted. ! ensureNonAbsolute(path); ! path = resolveAndNormalize(destination, convertedpath); ! // Create the parent directories if necessary ! File parent = path.getParentFile(); ! if (!parent.exists()) ! Files.mkdirs(parent, path.getName()); ! return path; } ! private File computeRealPath(SectionType type, ! String storedpath) throws IOException { ! String dir = getSubdirOfSection(type); ! return computeRealPath(dir + File.separatorChar + storedpath); } private static void markNativeCodeExecutable(SectionType type, File file) { --- 490,571 ---- throws IOException { return readModuleInfo(in, csize); // signature has the same format } ! // Track files installed outside the module library. For later removal. ! // files are relative to the modules directory. ! private PrintWriter filesWriter; ! private void trackFiles(SectionType type, File file) ! throws IOException ! { ! if (file == null || file.toPath().startsWith(destination.toPath())) ! return; ! // Lazy construction, not all modules will need this. ! if (filesWriter == null) ! filesWriter = new PrintWriter(computeRealPath("files"), "UTF-8"); ! filesWriter.println(Files.convertSeparator(relativize(destination, file))); ! filesWriter.flush(); } ! void remove() throws IOException { ! ModuleFile.Reader.remove(destination); ! } ! ! // Removes a module, given its module install directory ! static void remove(File moduleDir) throws IOException { ! // Firstly remove any files installed outside of the module dir ! File files = new File(moduleDir, "files"); ! if (files.exists()) { ! try (FileInputStream fis = new FileInputStream(files); ! InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); ! BufferedReader in = new BufferedReader(isr)) { ! String filename; ! while ((filename = in.readLine()) != null) ! Files.delete(new File(moduleDir, ! Files.platformSeparator(filename))); ! } ! } ! ! Files.deleteTree(moduleDir); ! } ! ! // Returns the absolute path of the given section type. ! private File getDirOfSection(SectionType type) { ! if (type == SectionType.NATIVE_LIBS) ! return natlibs; ! else if (type == SectionType.NATIVE_CMDS) ! return natcmds; ! else if (type == SectionType.CONFIG) ! return configs; ! ! // resolve sub dir section paths against the modules directory ! return new File(destination, ModuleFile.getSubdirOfSection(type)); ! } ! ! private File computeRealPath(String path) throws IOException { ! return resolveAndNormalize(destination, path); ! } ! ! private File computeRealPath(SectionType type, String storedpath) throws IOException { ! File sectionPath = getDirOfSection(type); ! File realpath = new File(sectionPath, ! Files.ensureNonAbsolute(Files.platformSeparator(storedpath))); ! ! validatePath(sectionPath, realpath); ! ! // Create the parent directories if necessary ! File parent = realpath.getParentFile(); ! if (!parent.exists()) ! Files.mkdirs(parent, realpath.getName()); ! ! return realpath; } private static void markNativeCodeExecutable(SectionType type, File file) {
*** 502,511 **** --- 575,591 ---- { file.setExecutable(true); } } + private void postExtract(SectionType type, File path) + throws IOException + { + markNativeCodeExecutable(type, path); + trackFiles(type, path); + } + private void unpack200gzip(DataInputStream in) throws IOException { GZIPInputStream gis = new GZIPInputStream(in) { public void close() throws IOException {} }; Pack200.Unpacker unpacker = Pack200.newUnpacker();
*** 577,591 **** throws IOException { copyStream(in, (DataOutput) new DataOutputStream(out), count); } - private static void ensureNonAbsolute(File path) throws IOException { - if (path.isAbsolute()) - throw new IOException("Abolute path instead of relative: " + path); - } - private static void ensureNonNegativity(long size, String parameter) { if (size < 0) throw new IllegalArgumentException(parameter + "<0: " + size); } --- 657,666 ----
*** 674,683 **** --- 749,774 ---- throw new IOException("Bogus relative path: " + path); return realpath; } + + private static String relativize(File directory, File path) throws IOException { + return (directory.toPath().relativize(path.toPath().toRealPath())).toString(); + } + + private static void validatePath(File parent, File child) + throws IOException + { + if (!child.toPath().startsWith(parent.toPath()) ) + throw new IOException("Bogus relative path: " + child); + if (child.exists()) { + // conflict, for now just fail + throw new IOException("File " + child + " already exists"); + } + } + private static short readHashLength(DataInputStream in) throws IOException { final short hashLength = in.readShort(); ensureNonNegativity(hashLength, "hashLength"); return hashLength;