JDK-4835956 : Crash when opening a MIDI file
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.sound
  • Affected Version: 1.4.2
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2003-03-21
  • Updated: 2003-08-02
  • Resolved: 2003-03-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2 b19Fixed
Related Reports
Relates :  
Description

Name: fb126949			Date: 03/21/2003


This is a spin-off of bug 4795377: closing sequencer sometimes crashes the VM. It was thought that this crash and the crash reported in the other bug have the same cause. Now that the cause of the loader crash is found, it is unlikely that it causes the close() crash, so I leave the other bug as it is.

When opening the file allaroun.mid (attached) twice with the Sequencer.setSequence(InputStream) method, Java Sound crashes the VM.

The MIDI file in question is corrupt, it has a wrong track length field. This should either cause an InvalidMidiDataException, or ignore the error and abort parsing the MIDI file. Under no circumstances should a MIDI file that weas downloaded from the Internet cause a crash.

The following program is used to reproduce the crash. Run it with

java MidiFileTester allaroun.mid allaroun.mid

It is important to specify the MIDI file twice, otherwise the internal buffer overrun is unlikely to occur.
import    java.io.*;
import    javax.sound.midi.*;

public class MidiFileTester {
    
    // 0: test with MidiSystem.getSequence(File)
    // 1: test with MidiSystem.getSequence(InputStream)
    // 2: test with Sequencer.setSequence(InputStream)
    static int TEST_METHOD=2;
    
    public static void main(String[] args) throws Exception {
	if (args.length == 0) {
	    System.out.println("No parameter specified");
	    System.exit(1);
	}
	int total=0; int succ=0;
	long startTime=System.currentTimeMillis();

	switch (TEST_METHOD) {
	    case 0: System.out.println("Test using" 
               +"MidiSystem.getSequence(File)"); 
               break;
	    case 1: System.out.println("Test using"
               +"MidiSystem.getSequence(InputStream)");
               break;
	    case 2: System.out.println("Test using"
               +"Sequencer.setSequence(InputStream)"); 
               break;
	}
    
	Sequencer s = null;    
	if (TEST_METHOD==2) {
	    s = MidiSystem.getSequencer();
	    s.open();
	}

	for (int i=0; i<args.length; i++) {
	    String    filename = args[i];
	    File    midiFile = new File(filename);
	    if  (!midiFile.exists()) {
		continue;
	    }
	    System.out.print(""+i+": "+filename+"...");
	    total++;
	    try {
		//MidiFileFormat mff = MidiSystem.getMidiFileFormat(midiFile);
		if (TEST_METHOD == 0) {
		    Sequence seq = MidiSystem.getSequence(midiFile);
		}
		if ((TEST_METHOD == 1) || (TEST_METHOD == 2)) {
		    BufferedInputStream bis = new BufferedInputStream(new 
		           FileInputStream(midiFile));
		    if (TEST_METHOD == 1) {
			Sequence seq = MidiSystem.getSequence(bis);
		    } else {
			s.setSequence(bis);
		    }
		}
		succ++;
		System.out.println("OK");
	    } catch (Exception e) {
		System.out.println("FAILED:"+e.toString());
	    }
	}
	if (TEST_METHOD==2) {
	    s.close();
	}
	System.out.println(""+succ+"/"+total
             +" successful. Failed:"+(total-succ));
	long duration=System.currentTimeMillis()-startTime;
	System.out.println("Duration: "+(duration / 1000)
             +"s "+(duration % 1000)+"ms");
	System.exit(0);
    }
}

===============================================================================
javafun:/home/heidiche/sound/4835956 26 % /net/koori.sfbay/p/jdk01/jdk/1.4.2/beta/b19/binaries/solaris-sparc/bin/java OpenCrash allaround.mid
Test usingSequencer.setSequence(InputStream)
0: ./allaroun.mid...OK
1: ./allaroun.mid...OK
2: ./allaroun.mid...OK
Duration: 4s 640ms
3/3 successful. 
test SUCCESSFUL (i.e. no crash...)

Verified successful in Sol8.

###@###.### 2003-03-26
=====================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis-beta tiger FIXED IN: mantis-beta tiger INTEGRATED IN: mantis-b19 mantis-beta tiger tiger-b14 VERIFIED IN: mantis-beta
14-06-2004

PUBLIC COMMENTS Crash when opening a MIDI file allaroun.mid.
10-06-2004

EVALUATION ###@###.### 2003-03-21 Easy to reproduce crash, riskless fix by adding bounds checks while parsing the MIDI file.
21-03-2003