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

InflaterInputStream.read(b..) and its subclasses work incorrectly with len & off

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 1.2.0
    • Fix Version/s: 1.3.0
    • Component/s: tools
    • Labels:
    • Subcomponent:
      jar
    • Resolved In Build:
      kestrel
    • CPU:
      sparc
    • OS:
      solaris_2.6

      Description



      Name: saC57035 Date: 12/01/98


      java.util.zip.InflaterInputStream.read(b,off,len) doesn't throw IndexOutOfBoundsException
      if either len or off parameter is negative in JDK-1.2fcs.

      java.util.zip.ZipInputStream.read(b,off,len), java.util.zip.GZIPInputStream.read(b,off,len),
      java.util.jar.JarInputStream.read(b,off,len) also inherit this incorrect behavior
      in JDK-1.2fcs.

      The general contract for the read method (see JLS item 22.3.3) clearly states:

      "22.3.3 public int read(byte[] bytes, int offset,
      int length) throws IOException,
      NullPointerException, IndexOutOfBoundsException

      < skipped >

      If off is negative, or len is negative, or off+len is greater than the
      length of the array b, then an IndexOutOfBoundsException is
      thrown."

      An example to check the following methods :
      java.util.zip.InflaterInputStream.read(b,off,len),
      java.util.zip.GZIPInputStream.read(b,off,len),
      java.util.zip.ZipInputStream.read(b,off,len),
      java.util.jar.JarInputStream.read(b,off,len)
      being called with incorrect off, len:

      ===== Test10.java ========
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.OutputStream;
      import java.io.ByteArrayInputStream;
      import java.io.ByteArrayOutputStream;
      import java.util.zip.*;
      import java.util.jar.*;


      public class Test10 {

        static final String manifestStream =
          "Manifest-Version: 1.0\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/AssertionTest.class\n"+
          "Digest-Algorithms: MD5, SHA\n"+
          "MD5-Digest: edwjehdgwjedgwj\n"+
          "SHA-Digest: eqweqweqwe\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/AssertionTest$ExpectedException.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/AssertionTest$ExceptionSet.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/AssertionTest$Fault.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/Factory.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/ImmutableObjectFactory.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/Generator.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/GridGenerator.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/SingletonGenerator.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/PrintReporter.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/Reporter.class\n\n"+
          "Name: javasoft/sqe/javatest/lib/apitest/SummaryReporter.class";

        public static void close (OutputStream os) {
          try {
          os.close();
          } catch (java.io.IOException e) {
             throw new RuntimeException("Unexpected "+e);
          }
        }
        
        public static boolean readTest (InputStream is) {

          byte[] b = new byte[200];
          int a;
          boolean passed = true;

          for(int j=0;j<b.length;j++) b[j] = (byte)(j+3); // Fill input data array somehow
          
          try {

             try { //CASE 1
                is.read(b, 0, -100); //len negative
                System.out.println( "CASE1: Failed - IndexOutOfBoundsException is not thrown" );
                passed = false;
             }
             catch(IndexOutOfBoundsException ib) {
                System.out.println( "CASE1: OK - IndexOutOfBoundsException thrown" );
             }

             try { //CASE 2
                is.read(b, 190, Integer.MIN_VALUE);
                System.out.println( "CASE2: Failed - IndexOutOfBoundsException is not thrown" );
                passed = false;
             }
             catch(IndexOutOfBoundsException ib) {
                System.out.println( "CASE2: OK - IndexOutOfBoundsException thrown" );
             }

             try { //CASE 3
                is.read(b, 0, 500); //len+off > b.length
                System.out.println( "CASE3: Failed - IndexOutOfBoundsException is not thrown" );
                passed = false;
             }
             catch(IndexOutOfBoundsException ib) {
                System.out.println( "CASE3: OK - IndexOutOfBoundsException thrown" );
             }
                         

             try { //CASE 4
                is.read(b, -100, 0); //off negative
                System.out.println( "CASE4: Failed - IndexOutOfBoundsException is not thrown" );
                passed = false;
             }
             catch(IndexOutOfBoundsException ib) {
                System.out.println( "CASE4: OK - IndexOutOfBoundsException thrown" );
             }

             try { //CASE 5
                is.read(b, Integer.MIN_VALUE, 10);
                System.out.println( "CASE5: Failed - IndexOutOfBoundsException is not thrown" );
                passed = false;
             }
             catch(IndexOutOfBoundsException ib) {
                System.out.println( "CASE5: OK - IndexOutOfBoundsException thrown" );
             }

             try { //CASE 6
                is.read(b, 500, 10); //len+off > b.length
                System.out.println( "CASE6: Failed - IndexOutOfBoundsException is not thrown" );
                passed = false;
                
             }
             catch(IndexOutOfBoundsException ib) {
                System.out.println( "CASE6: OK - IndexOutOfBoundsException thrown" );
             }
                         
            if(!(
                (a=is.read(new byte[183],0,183)) == 183 // Test no readings made
              ))
                 { System.out.println("Failed: Unexpected readings performed: "+
                                   (183-a)+ " bytes");
                   return false;
            }
            for(int j=0;j<b.length;j++)
              if (!(
                     b[j] == (byte)(j+3) // Test bytes are untouched
                 )) { System.out.println( "Failed: bytes are touched: j="+j);
                      return false;
              }
          }
          catch(Throwable e) { // Test no other exceptions thrown
           System.out.println( "Unexpected "+e+" thrown" );
           return false;
          }
          return passed;
        }
        public static void main (String argv[]) {

          InflaterInputStream iis = null;
          DeflaterOutputStream dos = null;
          GZIPInputStream gis = null;
          GZIPOutputStream gos = null;
          ZipInputStream zis = null;
          ZipOutputStream zo = null;
          JarInputStream jis = null;
          JarOutputStream jo = null;
          ByteArrayOutputStream out=null;
          Manifest manifest = null;
          
          byte[] data = new byte[183];

          for (int i=0; i<183; i++) data[i]=(byte)(i-3);

          try {
            // GZIPInputStream Testing
            out=new ByteArrayOutputStream();
            gos = new GZIPOutputStream(out); // open output
            gos.write(data,0,183);
            gos.close();
            gis = new GZIPInputStream(new ByteArrayInputStream(out.toByteArray())); // create input
            if ( readTest(gis) )
               System.out.println("GZIPInputStream Test Passed OK !");
            else System.out.println("GZIPInputStream Test Failed !");
            
            // InflaterInputStream Testing
            out=new ByteArrayOutputStream();
            dos = new DeflaterOutputStream(out); // open output
            dos.write(data,0,183);
            dos.close();
            iis = new InflaterInputStream(new ByteArrayInputStream(out.toByteArray())); // create input
            if ( readTest(iis) )
               System.out.println("InflaterInputStream Test Passed OK !");
            else System.out.println("InflaterInputStream Test Failed !");
                  
            // ZipInputStream Testing
            out=new ByteArrayOutputStream();
            zo = new ZipOutputStream(out); // open output
            zo.putNextEntry(new ZipEntry("entry1"));
            zo.write(data);
            zo.closeEntry();
            zo.close();
            zis = new ZipInputStream(new ByteArrayInputStream(out.toByteArray())); // create input
            zis.getNextEntry();
            if ( readTest(zis) )
               System.out.println("ZipInputStream Test Passed OK !");
            else System.out.println("ZipInputStream Test Failed !");

            // JarInputStream Testing
            out=new ByteArrayOutputStream();
            manifest = new Manifest(new ByteArrayInputStream(manifestStream.getBytes("ISO8859_1")));
            jo = new JarOutputStream(out); // open output
            jo.putNextEntry(new JarEntry("entry1"));
            jo.write(data);
            jo.closeEntry();
            jo.close();
            
            jis = new JarInputStream(new ByteArrayInputStream(out.toByteArray())); // create input
            jis.getNextJarEntry();

            if ( readTest(jis) )
               System.out.println("JarInputStream Test Passed OK !");
            else System.out.println("JarInputStream Test Failed !");
            
          } catch (Throwable e) {
              close(gos);
              System.out.println("Unexpected "+e);
          }

          return;
        

        }
        
      }

      ========= Sample run (JDK-1.2fcs-U) ==========
      #>javac Test10.java
      #>java Test10
      CASE1: Failed - IndexOutOfBoundsException is not thrown
      CASE2: Failed - IndexOutOfBoundsException is not thrown
      CASE3: OK - IndexOutOfBoundsException thrown
      CASE4: OK - IndexOutOfBoundsException thrown
      CASE5: OK - IndexOutOfBoundsException thrown
      CASE6: OK - IndexOutOfBoundsException thrown
      GZIPInputStream Test Failed !
      CASE1: Failed - IndexOutOfBoundsException is not thrown
      CASE2: Failed - IndexOutOfBoundsException is not thrown
      CASE3: OK - IndexOutOfBoundsException thrown
      CASE4: Failed - IndexOutOfBoundsException is not thrown
      CASE5: OK - IndexOutOfBoundsException thrown
      CASE6: OK - IndexOutOfBoundsException thrown
      InflaterInputStream Test Failed !
      CASE1: Failed - IndexOutOfBoundsException is not thrown
      CASE2: Failed - IndexOutOfBoundsException is not thrown
      CASE3: OK - IndexOutOfBoundsException thrown
      CASE4: OK - IndexOutOfBoundsException thrown
      CASE5: OK - IndexOutOfBoundsException thrown
      CASE6: OK - IndexOutOfBoundsException thrown
      ZipInputStream Test Failed !
      CASE1: Failed - IndexOutOfBoundsException is not thrown
      CASE2: Failed - IndexOutOfBoundsException is not thrown
      CASE3: OK - IndexOutOfBoundsException thrown
      CASE4: OK - IndexOutOfBoundsException thrown
      CASE5: OK - IndexOutOfBoundsException thrown
      CASE6: OK - IndexOutOfBoundsException thrown
      JarInputStream Test Failed !

      ======================================================================

        Attachments

          Activity

            People

            • Assignee:
              zlisunw Zhenghua Li (Inactive)
              Reporter:
              savzan Stanislav Avzan (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported:
                Indexed: