List of usage examples for org.apache.commons.compress.archivers.zip ZipArchiveOutputStream ZipArchiveOutputStream
public ZipArchiveOutputStream(File file) throws IOException
From source file:com.naryx.tagfusion.expression.function.file.Zip.java
public cfData execute(cfSession session, cfArgStructData argStruct, List<cfZipItem> zipItems) throws cfmRunTimeException { String destStr = getNamedStringParam(argStruct, "zipfile", null); if (destStr.length() == 0 || destStr == null) { throwException(session, "Missing the ZIPFILE argument or is an empty string."); }/*w w w. ja v a2s. c o m*/ String sourceStr = getNamedStringParam(argStruct, "source", null); File src = null; if (sourceStr != null) { if (sourceStr.length() == 0) { throwException(session, "SOURCE specified is an empty string. It is not a valid path."); } else { src = new File(sourceStr); // Check if src is a valid file/directory checkZipfile(session, src); } } boolean recurse = getNamedBooleanParam(argStruct, "recurse", true); String prefixStr = getNamedStringParam(argStruct, "prefix", ""); String prefix = prefixStr.replace('\\', '/'); if (prefix.length() != 0 && !prefix.endsWith("/")) { prefix = prefix + "/"; } String newpath = getNamedStringParam(argStruct, "newpath", null); if (newpath != null) { if (newpath.length() == 0) { throwException(session, "NEWPATH specified is an empty string. It is not a valid path."); } } boolean overwrite = getNamedBooleanParam(argStruct, "overwrite", false); int compressionLevel = getNamedIntParam(argStruct, "compressionlevel", ZipArchiveOutputStream.DEFLATED); if (compressionLevel < 0 || compressionLevel > 9) { throwException(session, "Invalid COMPRESSIONLEVEL specified. Please specify a number from 0-9 (inclusive)."); } String filterStr = getNamedStringParam(argStruct, "filter", null); FilenameFilter filter = null; if (filterStr != null) { filter = new filePatternFilter(filterStr, true); } String charset = getNamedStringParam(argStruct, "charset", System.getProperty("file.encoding")); // Destination file File zipfile = new File(destStr); // OVERWRITE if (zipfile.exists() && overwrite) { zipfile.delete(); } else if (zipfile.exists() && !overwrite) { throwException(session, "Cannot overwrite the existing file"); } ZipArchiveOutputStream zipOut = null; FileOutputStream fout = null; File parent = zipfile.getParentFile(); if (parent != null) { // create parent directories if required parent.mkdirs(); } try { fout = new FileOutputStream(zipfile); } catch (IOException e) { throwException(session, "Failed to create zip file: [" + zipfile.getAbsolutePath() + "]. Reason: " + e.getMessage()); } try { zipOut = new ZipArchiveOutputStream(fout); zipOut.setEncoding(charset); zipOut.setFallbackToUTF8(true); zipOut.setUseLanguageEncodingFlag(true); zipOut.setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy.ALWAYS); // Code for Zipparams if (zipItems != null) { Iterator<cfZipItem> srcItems = zipItems.iterator(); cfZipItem nextItem; while (srcItems.hasNext()) { nextItem = srcItems.next(); zipOperation(session, zipOut, nextItem.getFile(), nextItem.getRecurse(), nextItem.getPrefix(), compressionLevel, nextItem.getFilter(), nextItem.getNewPath()); } } // Code for function without zippparams zipOperation(session, zipOut, src, recurse, prefix, compressionLevel, filter, newpath); } finally { StreamUtil.closeStream(zipOut); StreamUtil.closeStream(fout); } return cfBooleanData.TRUE; }
From source file:com.facebook.buck.util.unarchive.UnzipTest.java
@Test public void testParentDirPaths() throws InterruptedException, IOException { try (ZipArchiveOutputStream zip = new ZipArchiveOutputStream(zipFile.toFile())) { // It seems very unlikely that a zip file would contain ".." paths, but handle it anyways. zip.putArchiveEntry(new ZipArchiveEntry("foo/bar/")); zip.closeArchiveEntry();// w ww . j a v a 2 s . co m zip.putArchiveEntry(new ZipArchiveEntry("foo/bar/../")); zip.closeArchiveEntry(); } Path extractFolder = tmpFolder.newFolder(); ArchiveFormat.ZIP.getUnarchiver().extractArchive(new DefaultProjectFilesystemFactory(), zipFile.toAbsolutePath(), extractFolder.toAbsolutePath(), ExistingFileMode.OVERWRITE_AND_CLEAN_DIRECTORIES); assertTrue(Files.exists(extractFolder.toAbsolutePath().resolve("foo"))); assertTrue(Files.exists(extractFolder.toAbsolutePath().resolve("foo/bar"))); }
From source file:fr.ortolang.diffusion.api.content.ContentResource.java
private ResponseBuilder handleExport(boolean followSymlink, String filename, String format, final List<String> paths, final Pattern pattern) throws UnsupportedEncodingException { ResponseBuilder builder;/*from w ww. ja va2s. c o m*/ switch (format) { case "zip": { LOGGER.log(Level.FINE, "exporting using format zip"); builder = Response.ok(); builder.header("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(filename, "utf-8") + ".zip"); builder.type("application/zip"); StreamingOutput stream = output -> { try (ZipArchiveOutputStream out = new ZipArchiveOutputStream(output)) { for (String path : paths) { try { String key = resolveContentPath(path); ArchiveEntryFactory factory = (name, time, size) -> { ZipArchiveEntry entry = new ZipArchiveEntry(name); if (time != -1) { entry.setTime(time); } if (size != -1) { entry.setSize(size); } return entry; }; exportToArchive(key, out, factory, PathBuilder.fromPath(path), false, pattern); } catch (AccessDeniedException e) { LOGGER.log(Level.FINEST, "access denied during export to zip", e); } catch (BrowserServiceException | CoreServiceException | AliasNotFoundException | KeyNotFoundException | OrtolangException e) { LOGGER.log(Level.INFO, "unable to export path to zip", e); } catch (InvalidPathException e) { LOGGER.log(Level.FINEST, "invalid path during export to zip", e); } catch (PathNotFoundException e) { LOGGER.log(Level.FINEST, "path not found during export to zip", e); } catch (ExportToArchiveIOException e) { LOGGER.log(Level.SEVERE, "unexpected IO error during export to archive, stopping export", e); break; } } } }; builder.entity(stream); break; } case "tar": { LOGGER.log(Level.FINE, "exporting using format tar"); builder = Response.ok(); builder.header("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(filename, "utf-8") + ".tar.gz"); builder.type("application/x-gzip"); StreamingOutput stream = output -> { try (GzipCompressorOutputStream gout = new GzipCompressorOutputStream(output); TarArchiveOutputStream out = new TarArchiveOutputStream(gout)) { for (String path : paths) { try { String key = resolveContentPath(path); ArchiveEntryFactory factory = (name, time, size) -> { TarArchiveEntry entry = new TarArchiveEntry(name); if (time != -1) { entry.setModTime(time); } if (size != -1) { entry.setSize(size); } return entry; }; exportToArchive(key, out, factory, PathBuilder.fromPath(path), false, pattern); } catch (BrowserServiceException | CoreServiceException | AliasNotFoundException | KeyNotFoundException | OrtolangException e) { LOGGER.log(Level.INFO, "unable to export path to tar", e); } catch (InvalidPathException e) { LOGGER.log(Level.FINEST, "invalid path during export to tar", e); } catch (PathNotFoundException e) { LOGGER.log(Level.FINEST, "path not found during export to tar", e); } catch (ExportToArchiveIOException e) { LOGGER.log(Level.SEVERE, "unexpected IO error during export to archive, stopping export", e); break; } } } }; builder.entity(stream); break; } default: builder = Response.status(Status.BAD_REQUEST).entity("export format [" + format + "] is not supported"); } return builder; }
From source file:fr.itldev.koya.alfservice.KoyaContentService.java
/** * * @param nodeRefs//w w w . j a v a 2 s.c o m * @return * @throws KoyaServiceException */ public File zip(List<String> nodeRefs) throws KoyaServiceException { File tmpZipFile = null; try { tmpZipFile = TempFileProvider.createTempFile("tmpDL", ".zip"); FileOutputStream fos = new FileOutputStream(tmpZipFile); CheckedOutputStream checksum = new CheckedOutputStream(fos, new Adler32()); BufferedOutputStream buff = new BufferedOutputStream(checksum); ZipArchiveOutputStream zipStream = new ZipArchiveOutputStream(buff); // NOTE: This encoding allows us to workaround bug... // http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4820807 zipStream.setEncoding("UTF-8"); zipStream.setMethod(ZipArchiveOutputStream.DEFLATED); zipStream.setLevel(Deflater.BEST_COMPRESSION); zipStream.setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy.ALWAYS); zipStream.setUseLanguageEncodingFlag(true); zipStream.setFallbackToUTF8(true); try { for (String nodeRef : nodeRefs) { addToZip(koyaNodeService.getNodeRef(nodeRef), zipStream, ""); } } catch (IOException e) { logger.error(e.getMessage(), e); throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); } finally { zipStream.close(); buff.close(); checksum.close(); fos.close(); } } catch (IOException | WebScriptException e) { logger.error(e.getMessage(), e); throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); } return tmpZipFile; }
From source file:com.facebook.buck.util.unarchive.UnzipTest.java
@Test public void testDirectoryPathsOverwriteFiles() throws InterruptedException, IOException { try (ZipArchiveOutputStream zip = new ZipArchiveOutputStream(zipFile.toFile())) { // It seems very unlikely that a zip file would contain ".." paths, but handle it anyways. zip.putArchiveEntry(new ZipArchiveEntry("foo/bar")); zip.closeArchiveEntry();/*from w w w . j a va 2s. com*/ } Path extractFolder = tmpFolder.newFolder(); Files.write(extractFolder.resolve("foo"), ImmutableList.of("whatever")); ArchiveFormat.ZIP.getUnarchiver().extractArchive(new DefaultProjectFilesystemFactory(), zipFile.toAbsolutePath(), extractFolder.toAbsolutePath(), ExistingFileMode.OVERWRITE_AND_CLEAN_DIRECTORIES); assertTrue(Files.exists(extractFolder.toAbsolutePath().resolve("foo"))); assertTrue(Files.exists(extractFolder.toAbsolutePath().resolve("foo/bar"))); }
From source file:at.spardat.xma.xdelta.test.JarDeltaJarPatcherTest.java
/** * Run jar patcher.//from w w w . j a v a 2 s . co m * * @param originalName the original name * @param targetName the target name * @param originalZip the original zip * @param newZip the new zip * @param comparefiles the comparefiles * @throws Exception the exception */ private void runJarPatcher(String originalName, String targetName, ZipFile originalZip, ZipFile newZip, boolean comparefiles) throws Exception { try (ZipArchiveOutputStream output = new ZipArchiveOutputStream(new FileOutputStream(patchFile))) { new JarDelta().computeDelta(originalName, targetName, originalZip, newZip, output); } ZipFile patch = new ZipFile(patchFile); ZipArchiveEntry listEntry = patch.getEntry("META-INF/file.list"); if (listEntry == null) { patch.close(); throw new IOException("Invalid patch - list entry 'META-INF/file.list' not found"); } BufferedReader patchlist = new BufferedReader(new InputStreamReader(patch.getInputStream(listEntry))); String next = patchlist.readLine(); String sourceName = next; next = patchlist.readLine(); new JarPatcher(patchFile.getName(), sourceName).applyDelta(patch, new ZipFile(originalName), new ZipArchiveOutputStream(new FileOutputStream(resultFile)), patchlist); if (comparefiles) { compareFiles(new ZipFile(targetName), new ZipFile(resultFile)); } }
From source file:com.github.braully.graph.DatabaseFacade.java
public static void allResultsZiped(OutputStream out) throws IOException { ZipArchiveOutputStream tOut = null;//from w w w . j a va2 s. c o m try { tOut = new ZipArchiveOutputStream(out); addFileToZip(tOut, DATABASE_DIRECTORY, ""); } finally { tOut.flush(); tOut.close(); } }
From source file:com.facebook.buck.util.unarchive.UnzipTest.java
@Test public void testStripsPrefixAndIgnoresSiblings() throws IOException { byte[] bazDotSh = "echo \"baz.sh\"\n".getBytes(Charsets.UTF_8); try (ZipArchiveOutputStream zip = new ZipArchiveOutputStream(zipFile.toFile())) { zip.putArchiveEntry(new ZipArchiveEntry("foo")); zip.closeArchiveEntry();//from ww w. j a va2 s .co m zip.putArchiveEntry(new ZipArchiveEntry("foo/bar/baz.txt")); zip.write(DUMMY_FILE_CONTENTS, 0, DUMMY_FILE_CONTENTS.length); zip.closeArchiveEntry(); ZipArchiveEntry exeEntry = new ZipArchiveEntry("foo/bar/baz.sh"); exeEntry.setUnixMode( (int) MorePosixFilePermissions.toMode(PosixFilePermissions.fromString("r-x------"))); exeEntry.setMethod(ZipEntry.STORED); exeEntry.setSize(bazDotSh.length); zip.putArchiveEntry(exeEntry); zip.write(bazDotSh); zip.closeArchiveEntry(); zip.putArchiveEntry(new ZipArchiveEntry("sibling")); zip.closeArchiveEntry(); zip.putArchiveEntry(new ZipArchiveEntry("sibling/some/dir/and/file.txt")); zip.write(DUMMY_FILE_CONTENTS, 0, DUMMY_FILE_CONTENTS.length); zip.closeArchiveEntry(); } Path extractFolder = Paths.get("output_dir", "nested"); ProjectFilesystem filesystem = TestProjectFilesystems.createProjectFilesystem(tmpFolder.getRoot()); ArchiveFormat.ZIP.getUnarchiver().extractArchive(zipFile, filesystem, extractFolder, Optional.of(Paths.get("foo")), ExistingFileMode.OVERWRITE_AND_CLEAN_DIRECTORIES); assertFalse(filesystem.isDirectory(extractFolder.resolve("sibling"))); assertFalse(filesystem.isDirectory(extractFolder.resolve("foo"))); assertFalse(filesystem.isDirectory(extractFolder.resolve("some"))); Path bazDotTxtPath = extractFolder.resolve("bar").resolve("baz.txt"); Path bazDotShPath = extractFolder.resolve("bar").resolve("baz.sh"); assertTrue(filesystem.isDirectory(extractFolder.resolve("bar"))); assertTrue(filesystem.isFile(bazDotTxtPath)); assertTrue(filesystem.isFile(bazDotShPath)); assertTrue(filesystem.isExecutable(bazDotShPath)); assertEquals(new String(bazDotSh), filesystem.readFileIfItExists(bazDotShPath).get()); assertEquals(new String(DUMMY_FILE_CONTENTS), filesystem.readFileIfItExists(bazDotTxtPath).get()); }
From source file:cz.muni.fi.xklinec.zipstream.Mallory.java
/** * Entry point. /*from w w w. jav a 2 s . c om*/ * * @param args * @throws FileNotFoundException * @throws IOException * @throws NoSuchFieldException * @throws ClassNotFoundException * @throws NoSuchMethodException * @throws java.lang.InterruptedException * @throws java.lang.CloneNotSupportedException */ public void doMain(String[] args) throws FileNotFoundException, IOException, NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, InterruptedException, CloneNotSupportedException { // command line argument parser CmdLineParser parser = new CmdLineParser(this); // if you have a wider console, you could increase the value; // here 80 is also the default parser.setUsageWidth(80); try { // parse the arguments. parser.parseArgument(args); } catch (CmdLineException e) { // if there's a problem in the command line, // you'll get this exception. this will report // an error message. System.err.println(e.getMessage()); System.err.println("java Mallory [options...] arguments..."); // print the list of available options parser.printUsage(System.err); System.err.println(); // print option sample. This is useful some time System.err.println(" Example: java Mallory " + parser.printExample(ExampleMode.ALL)); return; } if (arguments.size() == 2) { final String a0 = arguments.get(0); final String a1 = arguments.get(1); if (!quiet) System.err .println(String.format("Will use file [%s] as input file and [%s] as output file", a0, a1)); fis = new FileInputStream(a0); fos = new FileOutputStream(a1); } else if (arguments.isEmpty()) { if (!quiet) System.err .println(String.format("Will use file [STDIN] as input file and [STDOUT] as output file")); fis = System.in; fos = System.out; } else { if (!quiet) System.err.println("I do not understand the usage."); return; } if (zipAlign) { System.err.println("WARNING: ZIP Align feature not implemented yet..."); return; } // Deflater to re-compress uncompressed data read from ZIP stream. def = new Deflater(9, true); sentFiles = new HashSet<String>(); // Buffer input stream so input stream is read in chunks bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); // Effective temporary dir - if separate is required if (separateTempDir) { effectiveTempDir = File.createTempFile("temp_apk_dir_", "", new File(TEMP_DIR)); effectiveTempDir.delete(); effectiveTempDir.mkdir(); } else { effectiveTempDir = new File(TEMP_DIR); } // Generate temporary APK filename tempApk = File.createTempFile("temp_apk_", ".apk", effectiveTempDir); if (tempApk.canWrite() == false) { throw new IOException("Temp file is not writable!"); } FileOutputStream tos = new FileOutputStream(tempApk); // What we want here is to read input stream from the socket/pipe // whatever, process it in ZIP logic and simultaneously to copy // all read data to the temporary file - this reminds tee command // logic. This functionality can be found in TeeInputStream. TeeInputStream tis = new TeeInputStream(bis, tos); // Providing tis to ZipArchiveInputStream will copy all read data // to temporary tos file. zip = new ZipArchiveInputStream(tis); // List of all sent files, with data and hashes alMap = new HashMap<String, PostponedEntry>(); // Output stream // If there is defined slow down stream, it is used for user output to // mitigate tampering time gap. OutputStream osToUse = bos; SlowDownStream sdStream = null; if (slowDownStream) { // New slow down output stream with internal pipe buffer 15MB. sdStream = new SlowDownStream(osToUse, 15 * 1024 * 1024); // If size of the APK is known, use it to set slow down parameters correctly. if (apkSize > 0) { setSlowDownParams(); } if (!quiet) { System.err.println(String.format("Slown down stream will be used; apkSize=%d buffer=%d timeout=%d", apkSize, slowDownBuffer, slowDownTimeout)); } sdStream.setFlushBufferSize(slowDownBuffer); sdStream.setFlushBufferTimeout(slowDownTimeout); sdStream.start(); osToUse = sdStream; } zop = new ZipArchiveOutputStream(osToUse); zop.setLevel(9); if (!quiet) { System.err.println("Patterns that will be excluded:"); for (String regex : exclude) { System.err.println(" '" + regex + "'"); } System.err.println(); } // Read the archive ZipArchiveEntry ze = zip.getNextZipEntry(); while (ze != null) { ZipExtraField[] extra = ze.getExtraFields(true); byte[] lextra = ze.getLocalFileDataExtra(); UnparseableExtraFieldData uextra = ze.getUnparseableExtraFieldData(); byte[] uextrab = uextra != null ? uextra.getLocalFileDataData() : null; byte[] ex = ze.getExtra(); // ZipArchiveOutputStream.DEFLATED // // Data for entry byte[] byteData = Utils.readAll(zip); byte[] deflData = new byte[0]; int infl = byteData.length; int defl = 0; // If method is deflated, get the raw data (compress again). // Since ZIPStream automatically decompresses deflated files in read(). if (ze.getMethod() == ZipArchiveOutputStream.DEFLATED) { def.reset(); def.setInput(byteData); def.finish(); byte[] deflDataTmp = new byte[byteData.length * 2]; defl = def.deflate(deflDataTmp); deflData = new byte[defl]; System.arraycopy(deflDataTmp, 0, deflData, 0, defl); } if (!quiet) System.err.println(String.format( "ZipEntry: meth=%d " + "size=%010d isDir=%5s " + "compressed=%07d extra=%d lextra=%d uextra=%d ex=%d " + "comment=[%s] " + "dataDesc=%s " + "UTF8=%s " + "infl=%07d defl=%07d " + "name [%s]", ze.getMethod(), ze.getSize(), ze.isDirectory(), ze.getCompressedSize(), extra != null ? extra.length : -1, lextra != null ? lextra.length : -1, uextrab != null ? uextrab.length : -1, ex != null ? ex.length : -1, ze.getComment(), ze.getGeneralPurposeBit().usesDataDescriptor(), ze.getGeneralPurposeBit().usesUTF8ForNames(), infl, defl, ze.getName())); final String curName = ze.getName(); // Store zip entry to the map for later check after the APK is recompiled. // Hashes will be compared with the modified APK files after the process. PostponedEntry al = new PostponedEntry(ze, byteData, deflData); alMap.put(curName, al); // META-INF files should be always on the end of the archive, // thus add postponed files right before them if (isPostponed(ze)) { // Capturing interesting files for us and store for later. // If the file is not interesting, send directly to the stream. if (!quiet) System.err.println(" Interesting file, postpone sending!!!"); } else { // recompute CRC? if (recomputeCrc) { crc.reset(); crc.update(byteData); final long newCrc = crc.getValue(); if (!quiet && ze.getCrc() != newCrc && ze.getCrc() != -1) { System.err.println(" Warning: file CRC mismatch!!! Original: [" + ze.getCrc() + "] real: [" + newCrc + "]"); } ze.setCrc(newCrc); } // Write ZIP entry to the archive zop.putArchiveEntry(ze); // Add file data to the stream zop.write(byteData, 0, infl); zop.closeArchiveEntry(); zop.flush(); // Mark file as sent. addSent(curName); } ze = zip.getNextZipEntry(); } // Flush buffers zop.flush(); fos.flush(); // Cleaning up stuff, all reading streams can be closed now. zip.close(); bis.close(); fis.close(); tis.close(); tos.close(); // // APK is finished here, all non-interesting files were sent to the // zop strem (socket to the victim). Now APK transformation will // be performed, diff, sending rest of the files to zop. // boolean doPadding = paddExtra > 0 || outBytes > 0; long flen = tempApk.length(); if (outBytes <= 0) { outBytes = flen + paddExtra; } if (!quiet) { System.err.println("\nAPK reading finished, going to tamper downloaded " + " APK file [" + tempApk.toString() + "]; filezise=[" + flen + "]"); System.err.println(String.format("Sent so far: %d kB in %f %% after adding padding it is %f %%", zop.getWritten() / 1024, 100.0 * (double) zop.getWritten() / (double) flen, 100.0 * (double) zop.getWritten() / ((double) (outBytes > 0 ? outBytes : flen)))); } // New APK was generated, new filename = "tempApk_tampered" newApk = new File(outFile == null ? getFileName(tempApk.getAbsolutePath()) : outFile); if (cmd == null) { // Simulation of doing some evil stuff on the temporary apk Thread.sleep(3000); if (!quiet) System.err.println( "Tampered APK file: " + " [" + newApk.toString() + "]; filezise=[" + newApk.length() + "]"); // // Since no tampering was performed right now we will simulate it by just simple // copying the APK file // FileUtils.copyFile(tempApk, newApk); } else { try { // Execute command String cmd2exec; switch (cmdFormat) { case 0: cmd2exec = cmd + " " + tempApk.getAbsolutePath(); break; case 1: cmd2exec = cmd.replaceAll(INPUT_APK_PLACEHOLDER, tempApk.getAbsolutePath()); break; case 2: cmd2exec = cmd.replaceAll(INPUT_APK_PLACEHOLDER, tempApk.getAbsolutePath()); cmd2exec = cmd2exec.replaceAll(OUTPUT_APK_PLACEHOLDER, newApk.getAbsolutePath()); break; default: throw new IllegalArgumentException("Unknown command format number"); } if (!quiet) { System.err.println("Command to be executed: " + cmd2exec); System.err.println("\n<CMDOUTPUT>"); } long cmdStartTime = System.currentTimeMillis(); CmdExecutionResult resExec = execute(cmd2exec, OutputOpt.EXECUTE_STD_COMBINE, null, quiet ? null : System.err); long cmdStopTime = System.currentTimeMillis(); if (!quiet) { System.err.println("</CMDOUTPUT>\n"); System.err.println("Command executed. Return value: " + resExec.exitValue + "; tamperingTime=" + (cmdStopTime - cmdStartTime)); } } catch (IOException e) { if (!quiet) e.printStackTrace(System.err); } } // // Now read new APK file with ZipInputStream and push new/modified files to the ZOP. // fis = new FileInputStream(newApk); bis = new BufferedInputStream(fis); zip = new ZipArchiveInputStream(bis); // Merge tampered APK to the final, but in this first time // do it to the external buffer in order to get final apk size. // Backup ZOP state to the clonned instance. zop.flush(); long writtenBeforeDiff = zop.getWritten(); ZipArchiveOutputStream zop_back = zop; zop = zop.cloneThis(); // Set temporary byte array output stream, so original output stream is not // touched in this phase. ByteArrayOutputStream bbos = new ByteArrayOutputStream(); zop.setOut(bbos); mergeTamperedApk(false, false); zop.flush(); // Now output stream almost contains APK file, central directory is not written yet. long writtenAfterDiff = zop.getWritten(); if (!quiet) System.err.println(String.format("Tampered apk size yet; writtenBeforeDiff=%d writtenAfterDiff=%d", writtenBeforeDiff, writtenAfterDiff)); // Write central directory header to temporary buffer to discover its size. zop.writeFinish(); zop.flush(); bbos.flush(); // Read new values long writtenAfterCentralDir = zop.getWritten(); long centralDirLen = zop.getCdLength(); byte[] buffAfterMerge = bbos.toByteArray(); //int endOfCentralDir = (int) (buffAfterMerge.length - (writtenAfterCentralDir-writtenBeforeDiff)); long endOfCentralDir = END_OF_CENTRAL_DIR_SIZE; // Determine number of bytes to add to APK. // padlen is number of bytes missing in APK to meet desired size in bytes. padlen = doPadding ? (outBytes - (writtenAfterCentralDir + endOfCentralDir)) : 0; // Compute number of files needed for padding. int padfiles = (int) Math.ceil((double) padlen / (double) (PAD_BLOCK_MAX)); if (!quiet) System.err.println(String.format("Remaining to pad=%d, padfiles=%d " + "writtenAfterCentralDir=%d " + "centralDir=%d endOfCentralDir=%d centralDirOffset=%d " + "buffSize=%d total=%d desired=%d ", padlen, padfiles, writtenAfterCentralDir, centralDirLen, endOfCentralDir, zop.getCdOffset(), buffAfterMerge.length, writtenAfterCentralDir + endOfCentralDir, outBytes)); if (padlen < 0) { throw new IllegalStateException("Padlen cannot be negative, please increase padding size"); } // Close input streams for tampered APK try { zip.close(); bis.close(); fis.close(); } catch (Exception e) { if (!quiet) e.printStackTrace(System.err); } // Merge again, now with pre-defined padding size. fis = new FileInputStream(newApk); bis = new BufferedInputStream(fis); zip = new ZipArchiveInputStream(bis); // Revert changes - use clonned writer stream. zop = zop_back; long writtenBeforeDiff2 = zop.getWritten(); // Merge tampered APK, now for real, now with computed padding. mergeTamperedApk(true, true); zop.flush(); long writtenAfterMerge2 = zop.getWritten(); // Finish really zop.finish(); zop.flush(); long writtenReally = zop.getWritten(); long centralDirLen2 = zop.getCdLength(); if (!quiet) System.err.println(String.format( "Write stats; " + "writtenBeforeDiff=%d writtenAfterDiff=%d " + "writtenAfterCentralDir=%d centralDir=%d endOfCd=%d centralDirOffset=%d " + "padlen=%d total=%d desired=%d", writtenBeforeDiff2, writtenAfterMerge2, writtenReally, centralDirLen2, endOfCentralDir, zop.getCdOffset(), padlen, writtenReally + endOfCentralDir, outBytes)); // Will definitelly close (and finish if not yet) ZOP stream // and close underlying stream. zop.close(); if (sdStream != null) { if (!quiet) { System.err.println("Waiting for sdStream to finish..."); } // Wait for stream to finish dumping with pre-set speed, if it takes // too long (1 minute) switch slown down stream to dumping mode // without any waiting. long startedDump = System.currentTimeMillis(); while (sdStream.isRunning()) { long curTime = System.currentTimeMillis(); if (startedDump != -1 && (curTime - startedDump) > 1000 * 120) { startedDump = -1; sdStream.flushPipes(); } Thread.sleep(10); } if (!quiet) { System.err.println("SD stream finished, terminating..."); } } // Should always be same if (!quiet && doPadding && writtenBeforeDiff != writtenBeforeDiff2) { System.err.println(String.format("Warning! Size before merge from pass1 and pass2 does not match.")); } // If size is different, something went wrong. if (!quiet && doPadding && ((writtenReally + endOfCentralDir) != outBytes)) { System.err.println(String.format("Warning! Output size differs from desired size.")); } bos.close(); fos.close(); // Delete temporary files if required if (deleteArtefacts) { try { if (newApk.exists()) { newApk.delete(); if (!quiet) System.err.println("Tampered APK removed. " + newApk.getAbsolutePath()); } if (tempApk.exists()) { tempApk.delete(); if (!quiet) System.err.println("Original APK removed. " + tempApk.getAbsolutePath()); } if (separateTempDir && effectiveTempDir.exists()) { FileUtils.deleteDirectory(effectiveTempDir); if (!quiet) System.err.println("Temporary directory removed. " + effectiveTempDir.getAbsolutePath()); } if (!quiet) System.err.println("Temporary files were removed."); } catch (IOException e) { if (!quiet) e.printStackTrace(System.err); } } if (!quiet) System.err.println("THE END!"); }
From source file:at.spardat.xma.xdelta.test.JarDeltaJarPatcherTest.java
/** * Tests JarDelta and JarPatcher on two identical files. * * @throws Exception the exception// www . ja v a2 s . c om */ @Test public void testJarPatcherIdentFile() throws Exception { ZipFile originalZip = makeSourceZipFile(sourceFile); new JarDelta().computeDelta(sourceFile.getAbsolutePath(), sourceFile.getAbsolutePath(), originalZip, originalZip, new ZipArchiveOutputStream(new FileOutputStream(patchFile))); ZipFile patch = new ZipFile(patchFile); ZipArchiveEntry listEntry = patch.getEntry("META-INF/file.list"); if (listEntry == null) { patch.close(); throw new IOException("Invalid patch - list entry 'META-INF/file.list' not found"); } BufferedReader patchlist = new BufferedReader(new InputStreamReader(patch.getInputStream(listEntry))); String next = patchlist.readLine(); String sourceName = next; next = patchlist.readLine(); ZipFile source = new ZipFile(sourceFile); new JarPatcher(patchFile.getName(), sourceName).applyDelta(patch, source, new ZipArchiveOutputStream(new FileOutputStream(resultFile)), patchlist); compareFiles(new ZipFile(sourceFile), new ZipFile(resultFile)); }