Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8231451

ZipFileInputStream.skip does not handle negative values correctly

XMLWordPrintable

    • b22
    • x86_64
    • windows_10

      A DESCRIPTION OF THE PROBLEM :
      When ZipFile.getInputStream is called for a STORED entry, a ZipFile$ZipFileInputStream is returned. The method skip(long) of this class is not correctly handling negative values.

      All (?) other implementations of InputStream either return 0 when the skip amount is <= 0, or throw an exception. However, ZipFileInputStream simply accepts the negative value, possibly even returning it as number of skipped bytes.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the provided code

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Either "0" is printed as skipped amount or an exception is thrown
      ACTUAL -
      "-100" is printed as number of skipped bytes

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.UncheckedIOException;
      import java.nio.file.Files;
      import java.nio.file.Path;
      import java.util.zip.CRC32;
      import java.util.zip.ZipEntry;
      import java.util.zip.ZipFile;
      import java.util.zip.ZipOutputStream;

      public class ZipFileInputStreamTest {
          public static void main(String[] args) throws IOException {
              Path tempFile = Files.createTempFile("zip-test", ".zip");
              try {
                  Files.write(tempFile, createZipFileData());
                  
                  try (ZipFile zipFile = new ZipFile(tempFile.toFile())) {
                      ZipEntry entry = zipFile.entries().nextElement();
                      InputStream entryIn = zipFile.getInputStream(entry);
                      
                      long skipped = entryIn.skip(-100);
                      System.out.println("Skipped: " + skipped);
                  }
              }
              finally {
                  Files.delete(tempFile);
              }
          }
          
          private static byte[] createZipFileData() {
              ByteArrayOutputStream out = new ByteArrayOutputStream();
              ZipOutputStream zipOut = new ZipOutputStream(out);
              
              try {
                  // STORED has to be used, DEFLATED would wrap stream inside ZipFileInflaterInputStream
                  // which prevents negative skip amounts
                  zipOut.setMethod(ZipEntry.STORED);
                  
                  ZipEntry zipEntry = new ZipEntry("test");
                  
                  byte[] data = new byte[] {'t', 'e', 's', 't'};
                  zipEntry.setSize(data.length);
                  
                  CRC32 crc32 = new CRC32();
                  crc32.update(data);
                  zipEntry.setCrc(crc32.getValue());
                  
                  zipOut.putNextEntry(zipEntry);
                  zipOut.write(data);
                  zipOut.finish();
              }
              catch (IOException ioException) {
                  throw new UncheckedIOException(ioException);
              }
              
              return out.toByteArray();
          }
      }
      ---------- END SOURCE ----------

            lancea Lance Andersen
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: