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

Cannot setBytes() if incoming buffer's length is bigger than number of elements we want to insert.

XMLWordPrintable

    • b22
    • generic
    • generic
    • Verified

      FULL PRODUCT VERSION :
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      I think is is not related to OS, but to Java Code.
      SunOS 5.11 11.2 sun4v sparc sun4v

      A DESCRIPTION OF THE PROBLEM :
      There is a problem in SerialBlob setBytes(long pos, byte[] bytes, int offset, int length) method. The condition which decides if bytes should be added to Blob is:
      while ( i < length || (offset + i +1) < (bytes.length-offset) )

      In my opinion || should be replaced by &&. If we send a big buffer and we tell to read from the beginning (offset=0) but only a few elements (length < bytes.length), all the bytes are indeed written, but then it crashes - it wants to write even when the internal buffer is smaller! The condition (i < length) says that we already wrote all we wanted and the loop should be finished. In reality the second part of the condition forces loop to continue which causes ArrayIndexOutOfBoundsException. I think (i < length) should be critical and break the loop.

      Why implementation does not use just System.arraycopy?

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      No error, bytes should be copied to SerialBlob
      ACTUAL -
      java.lang.ArrayIndexOutOfBoundsException: 10
      at javax.sql.rowset.serial.SerialBlob.setBytes(SerialBlob.java:378)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.ArrayIndexOutOfBoundsException: 10
      at javax.sql.rowset.serial.SerialBlob.setBytes(SerialBlob.java:378)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      try {
      byte[] source = new byte[10];
      Blob blob = new SerialBlob(new byte[source.length]);
      ByteArrayInputStream inputStream = new ByteArrayInputStream(source);
      int BUFFER_SIZE = 3;
      byte[] buffer = new byte[BUFFER_SIZE];
      int read, lastInsert = 1;
      read = inputStream.read(buffer, 0, BUFFER_SIZE);
      while (read != -1) {
      blob.setBytes(lastInsert, buffer, 0, read);
      lastInsert += read;
      read = inputStream.read(buffer, 0, BUFFER_SIZE);
      }
      inputStream.close();

      }catch (Exception e){
      e.printStackTrace();
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      try {
      byte[] source = new byte[10];
      Blob blob = new SerialBlob(new byte[source.length]);
      ByteArrayInputStream inputStream = new ByteArrayInputStream(source);
      int BUFFER_SIZE = 3;
      byte[] buffer = new byte[BUFFER_SIZE];
      int read, lastInsert = 1;
      read = inputStream.read(buffer, 0, BUFFER_SIZE);
      boolean changeBuffer = false;
      while (read != -1) {
      if (read != BUFFER_SIZE) {
                          /*needed because of bugged(?) blob.setBytes*/
      byte[] buffer2 = new byte[read];
      System.arraycopy(buffer, 0, buffer2, 0, read);
      buffer = buffer2;
      changeBuffer = true;
      }
      blob.setBytes(lastInsert, buffer, 0, read);
      lastInsert += read;
      if (changeBuffer) {
      buffer = new byte[BUFFER_SIZE];
      changeBuffer = !changeBuffer;
      }
      read = inputStream.read(buffer, 0, BUFFER_SIZE);
      }
      inputStream.close();

      }catch (Exception e){
      e.printStackTrace();
      }

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

              Created:
              Updated:
              Resolved: