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

Spec: SourceDataLine.write() throws unspecified ArrayIndexOutOfBoundsException

    Details

    • Subcomponent:
    • Resolved In Build:
      b28
    • CPU:
      generic
    • OS:
      generic

      Description


                      writtenBytes = -1;
                      try {
                          writtenBytes =
                              testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
                          out.println("> OK - number of written bytes = " + writtenBytes);
                      } catch (Throwable thrown) {
                          out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
                          out.println("# Unexpected Exception is thrown");
                          thrown.printStackTrace(out);
                          testResult = STATUS_FAILED;
                      }

                      testedSourceLine.close();

                  } // for (int j=0; j < supportedSourceLineInfo.length; j++)
                  installedMixer.close();

              } // for (int i=0; i < installedMixersInfo.length; i++)

              if ( testResult == STATUS_FAILED ) {
                  out.println("\n==> test FAILED!");
              } else {
                  out.println("\n==> test PASSED!");
              }
              return testResult;
          }
          
      } // end of test class
      -------------------------------------------------------------------------
       
      ======================================================================
      ###@###.### 2003-11-03
      Checked in fix
      Name: abR10010 Date: 05/10/2002




      The test (see below) shows that the SourceDataLine.write(byte[] b, int off, int len)
      method of the javax.sound.sampled.SourceDataLine interface throws an
      ArrayIndexOutOfBoundsException when incorrect arguments describing
      the data array to write are specified.

      Such behavior is shown for one source data line of one of installed on the system
      mixers when test runs with JDK 1.4.1-beta-b11.

      An ArrayIndexOutOfBoundsException is appropriate Exception for such cases but
      the specification says nothing about it.

      Also an IllegalArgumentException is appropriate Exception for such cases.

      It seems that the spec should be adjusted to describe these situations.


      Please, see test log:

      % java -version
      java version "1.4.1-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b11)
      Java HotSpot(TM) Client VM (build 1.4.1-beta-b11, mixed mode)

      % java test

      ==> Test for SourceDataLine.write() method:

      >>> Number of mixers installed on the system = 2

      >>> installedMixer[0] = com.sun.media.sound.HeadspaceMixer@117a8bd

      >> Number of SourceLineInfo supported by installedMixer = 2

      > testSourceLineInfo[0] = interface SourceDataLine supporting 8 audio formats
      > testedSourceLine = com.sun.media.sound.MixerSourceLine@21b6d

      > open tested SourceLine:
      > OK - line is opened

      > check SourceDataLine.write() for data length exceeding real size of data:
      > testedSourceLine.available() = 4
      > frame size = 4
      > real size of data to write = 4
      > offset of data to write = 0
      > number of bytes to write = 8
      ## SourceDataLine.write(byte[] b, int off, int len) failed:
      # Unexpected Exception is thrown
      java.lang.ArrayIndexOutOfBoundsException: 4
      at com.sun.media.sound.Toolkit.getByteSwapped(Toolkit.java:41)
      at com.sun.media.sound.CircularBuffer.write(CircularBuffer.java:67)
      at com.sun.media.sound.MixerSourceLine.write(MixerSourceLine.java:126)
      at test.run(test.java:193)
      at test.main(test.java:13)

      > check SourceDataLine.write() for negative offset of data:
      > testedSourceLine.available() = 4
      > frame size = 4
      > real size of data to write = 4
      > offset of data to write = -1
      > number of bytes to write = 4
      ## SourceDataLine.write(byte[] b, int off, int len) failed:
      # Unexpected Exception is thrown
      java.lang.ArrayIndexOutOfBoundsException: -1
      at com.sun.media.sound.Toolkit.getByteSwapped(Toolkit.java:41)
      at com.sun.media.sound.CircularBuffer.write(CircularBuffer.java:67)
      at com.sun.media.sound.MixerSourceLine.write(MixerSourceLine.java:126)
      at test.run(test.java:214)
      at test.main(test.java:13)

      > check SourceDataLine.write() when "offset + number of bytes to write" exceeds the bounds of data
      > testedSourceLine.available() = 4
      > frame size = 4
      > real size of data to write = 4
      > offset of data to write = 1
      > number of bytes to write = 4
      ## SourceDataLine.write(byte[] b, int off, int len) failed:
      # Unexpected Exception is thrown
      java.lang.ArrayIndexOutOfBoundsException: 4
      at com.sun.media.sound.Toolkit.getByteSwapped(Toolkit.java:42)
      at com.sun.media.sound.CircularBuffer.write(CircularBuffer.java:67)
      at com.sun.media.sound.MixerSourceLine.write(MixerSourceLine.java:126)
      at test.run(test.java:235)
      at test.main(test.java:13)

      > testSourceLineInfo[1] = interface Clip supporting 8 audio formats, and buffers of 0 to 4194304 bytes
      > testedSourceLine = com.sun.media.sound.MixerClip@124bbbf
      > testSourceLine is not SourceDataLine

      >>> installedMixer[1] = com.sun.media.sound.SimpleInputDevice@a20892

      >> Number of SourceLineInfo supported by installedMixer = 0

      ==> test FAILED!
       
       
      The test source:
      ------------------------------- test.java --------------------------------
      // File: %Z%%M% %I% %E%
      // Copyright %G% Sun Microsystems, Inc. All Rights Reserved

      import javax.sound.sampled.*;

      public class test {

          static final int STATUS_PASSED = 0;
          static final int STATUS_FAILED = 2;
          static final int STATUS_TEMP = 95;
          
          public static void main(String argv[]) {
              int testExitStatus = run(argv, System.out) + STATUS_TEMP;
              System.exit(testExitStatus);
          }

          public static int run(String argv[], java.io.PrintStream out) {
              int testResult = STATUS_PASSED;
          
              int framesNumberToExceed = 2;
              if ( argv.length > 0 ) {
                  try {
                      framesNumberToExceed = Integer.parseInt(argv[0]);
                  }
                  catch (NumberFormatException e) {
                  }
              }

              out.println
                  ("\n==> Test for SourceDataLine.write() method:");

              Mixer.Info[] installedMixersInfo = AudioSystem.getMixerInfo();
              
              if ( installedMixersInfo == null ) {
                  out.println("## AudioSystem.getMixerInfo() returned unexpected result:");
                  out.println("# expected: an array of Mixer.Info objects (may be array of length 0);");
                  out.println("# produced: null;");
                  return STATUS_FAILED;
              }

              if ( installedMixersInfo.length == 0 ) {
                  // there are no mixers installed on the system -
                  // so this testcase can not be tested
                  out.println("\n>>> There are no mixers installed on the system!");
                  return STATUS_PASSED;
              }

              out.println("\n>>> Number of mixers installed on the system = "
                  + installedMixersInfo.length);
              Mixer installedMixer = null;
              for (int i=0; i < installedMixersInfo.length; i++) {
                  try {
                      installedMixer = AudioSystem.getMixer(installedMixersInfo[i]);
                  } catch (SecurityException securityException) {
                      // installed Mixer is unavailable because of security restrictions
                      out.println("\n>>> installedMixer[" + i
                          + "] is unavailable because of security restrictions");
                      continue;
                  } catch (Throwable thrown) {
                      out.println("\n## installedMixer[" + i + "] is unavailable because of");
                      out.println("# AudioSystem.getMixer() threw unexpected exception:");
                      thrown.printStackTrace(out);
                      testResult = STATUS_FAILED;
                      continue;
                  }

                  out.println("\n>>> installedMixer["+i+"] = " + installedMixer);
                  try {
                      installedMixer.open();
                  } catch (LineUnavailableException lineUnavailableException) {
                      // installedMixer is not available due to resource restrictions
                      out.println(">> installedMixer[" + i
                          + "] is not opened because of resource restrictions");
                      continue;
                  } catch (SecurityException securityException) {
                      // installedMixer is not available due to security restrictions
                      out.println(">> installedMixer[" + i
                          + "] is not opened because of security restrictions");
                      continue;
                  } catch (Throwable thrown) {
                      out.println("## installedMixer.open() throws unexpected exception:");
                      thrown.printStackTrace(out);
                      testResult = STATUS_FAILED;
                      continue;
                  }
                  Line.Info supportedSourceLineInfo[] = null;
                  try {
                      supportedSourceLineInfo = installedMixer.getSourceLineInfo();
                  } catch (Throwable thrown) {
                      out.println("## installedMixer.getSourceLineInfo() throws "
                          + "unexpected exception:");
                      thrown.printStackTrace(out);
                      testResult = STATUS_FAILED;
                      installedMixer.close();
                      continue;
                  }
                  if ( supportedSourceLineInfo == null ) {
                      out.println("## installedMixer.getSourceLineInfo() returned null array");
                      out.println("# Mixer = " + installedMixer);
                      testResult = STATUS_FAILED;
                      installedMixer.close();
                      continue;
                  }
                  out.println("\n>> Number of SourceLineInfo supported by installedMixer = "
                      + supportedSourceLineInfo.length);

                  for (int j=0; j < supportedSourceLineInfo.length; j++) {
                      Line.Info testSourceLineInfo = supportedSourceLineInfo[j];
                      
                      out.println("\n> testSourceLineInfo["+j+"] = " + testSourceLineInfo);
                      Line testSourceLine = null;
                      try {
                          testSourceLine = installedMixer.getLine(testSourceLineInfo);
                      } catch (LineUnavailableException lineUnavailableException) {
                          // line is not available due to resource restrictions
                          out.println("> Line for this SourceLine Info is not available "
                              + "due to resource restrictions");
                          continue;
                      } catch (SecurityException securityException) {
                          // line is not available due to security restrictions
                          out.println("> Line for this SourceLine Info is not available "
                              + "due to security restrictions");
                          continue;
                      } catch (Throwable thrown) {
                          out.println("## installedMixer.getLine(testSourceLineInfo) throws "
                              + "unexpected Exception:");
                          thrown.printStackTrace(out);
                          testResult = STATUS_FAILED;
                          continue;
                      }

                      out.println("> testedSourceLine = " + testSourceLine);
                      if ( ! (testSourceLine instanceof SourceDataLine) ) {
                          out.println("> testSourceLine is not SourceDataLine");
                          continue;
                      }

                      SourceDataLine testedSourceLine = (SourceDataLine)testSourceLine;
                      AudioFormat lineAudioFormat = testedSourceLine.getFormat();

                      out.println("\n> open tested SourceLine:");
                      try {
                          testedSourceLine.open(lineAudioFormat);
                          out.println("> OK - line is opened");
                      } catch (LineUnavailableException lineUnavailableException) {
                          out.println("> Line is not available due to resource restrictions:");
                          lineUnavailableException.printStackTrace(out);
                          continue;
                      } catch (SecurityException securityException) {
                          out.println("> Line is not available due to security restrictions:");
                          securityException.printStackTrace(out);
                          continue;
                      } catch (Throwable thrown) {
                          out.println("## SourceDataLine.open(AudioFormat format) failed:");
                          out.println("# Unexpected Exception is thrown");
                          out.println("# Mixer = " + installedMixer);
                          out.println("# SourceDataLine = " + testedSourceLine);
                          thrown.printStackTrace(out);
                          testResult = STATUS_FAILED;
                          continue;
                      }
                      
                      testedSourceLine.start();

                      int frameSize = 1;
                      if ( lineAudioFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED ) {
                          frameSize = lineAudioFormat.getFrameSize();
                      } else {
                          if ( lineAudioFormat.getSampleSizeInBits() != AudioSystem.NOT_SPECIFIED ) {
                              frameSize = lineAudioFormat.getSampleSizeInBits()/8;
                              if ( lineAudioFormat.getSampleSizeInBits()%8 != 0 ) {
                                  frameSize++;
                              }
                          }
                      }
                      int bufferSizeToWrite = testedSourceLine.available();
                      bufferSizeToWrite = testedSourceLine.available();
                      byte[] dataToWrite = new byte[bufferSizeToWrite];
                      for (int k=0; k < bufferSizeToWrite; k++) {
                          dataToWrite[k] = (byte)1;
                      }
                      int offsetToWrite = 0;

                      out.println("\n> check SourceDataLine.write() for data length exceeding real size of
      data:");

                      out.println("> testedSourceLine.available() = " + testedSourceLine.available());
                      out.println("> frame size = " + frameSize);
                      out.println("> real size of data to write = " + bufferSizeToWrite);
                      out.println("> offset of data to write = " + offsetToWrite);
                      out.println("> number of bytes to write = " + (bufferSizeToWrite + frameSize));
                      int writtenBytes = -1;
                      try {
                          writtenBytes =
                              testedSourceLine.write(dataToWrite, offsetToWrite,
      bufferSizeToWrite+frameSize);
                          out.println("> OK - number of written bytes = " + writtenBytes);
                      } catch (Throwable thrown) {
                          out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
                          out.println("# Unexpected Exception is thrown");
                          thrown.printStackTrace(out);
                          testResult = STATUS_FAILED;
                      }


                      out.println("\n> check SourceDataLine.write() for negative offset of data:");

                      offsetToWrite = -1;
                      out.println("> testedSourceLine.available() = " + testedSourceLine.available());
                      out.println("> frame size = " + frameSize);
                      out.println("> real size of data to write = " + bufferSizeToWrite);
                      out.println("> offset of data to write = " + offsetToWrite);
                      out.println("> number of bytes to write = " + bufferSizeToWrite);
                      writtenBytes = -1;
                      try {
                          writtenBytes =
                              testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
                          out.println("> OK - number of written bytes = " + writtenBytes);
                      } catch (Throwable thrown) {
                          out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
                          out.println("# Unexpected Exception is thrown");
                          thrown.printStackTrace(out);
                          testResult = STATUS_FAILED;
                      }

                      out.println("\n> check SourceDataLine.write() when \"offset + number of bytes to
      write\""
                          + " exceeds the bounds of data");

                      offsetToWrite = 1;
                      out.println("> testedSourceLine.available() = " + testedSourceLine.available());
                      out.println("> frame size = " + frameSize);
                      out.println("> real size of data to write = " + bufferSizeToWrite);
                      out.println("> offset of data to write = " + offsetToWrite);
                      out.println("> number of bytes to write = " + bufferSizeToWrite);

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                kpsmith Kevin Smith (Inactive)
                Reporter:
                bondsunw Bond Bond (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: