8135160: Endless Loop in RiffReader
Reviewed-by: prr, amenkov
This commit is contained in:
parent
ebf2ca56f0
commit
da9e27a018
@ -548,7 +548,7 @@ public final class DLSSoundbank implements Soundbank {
|
||||
long count = riff.readUnsignedInt();
|
||||
|
||||
if (size - 8 != 0)
|
||||
riff.skipBytes(size - 8);
|
||||
riff.skip(size - 8);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
DLSModulator modulator = new DLSModulator();
|
||||
@ -568,7 +568,7 @@ public final class DLSSoundbank implements Soundbank {
|
||||
long count = riff.readUnsignedInt();
|
||||
|
||||
if (size - 8 != 0)
|
||||
riff.skipBytes(size - 8);
|
||||
riff.skip(size - 8);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
DLSModulator modulator = new DLSModulator();
|
||||
@ -661,7 +661,7 @@ public final class DLSSoundbank implements Soundbank {
|
||||
long loops = riff.readInt();
|
||||
|
||||
if (size > 20)
|
||||
riff.skipBytes(size - 20);
|
||||
riff.skip(size - 20);
|
||||
|
||||
for (int i = 0; i < loops; i++) {
|
||||
DLSSampleLoop loop = new DLSSampleLoop();
|
||||
@ -671,7 +671,7 @@ public final class DLSSoundbank implements Soundbank {
|
||||
loop.length = riff.readUnsignedInt();
|
||||
sampleOptions.loops.add(loop);
|
||||
if (size2 > 16)
|
||||
riff.skipBytes(size2 - 16);
|
||||
riff.skip(size2 - 16);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,6 +118,7 @@ public final class RIFFReader extends InputStream {
|
||||
return ckSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (avail == 0) {
|
||||
return -1;
|
||||
@ -132,6 +133,7 @@ public final class RIFFReader extends InputStream {
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int offset, int len) throws IOException {
|
||||
if (avail == 0) {
|
||||
return -1;
|
||||
@ -172,49 +174,45 @@ public final class RIFFReader extends InputStream {
|
||||
}
|
||||
}
|
||||
|
||||
public long skipBytes(long n) throws IOException {
|
||||
if (n < 0)
|
||||
@Override
|
||||
public long skip(final long n) throws IOException {
|
||||
if (n <= 0 || avail == 0) {
|
||||
return 0;
|
||||
long skipped = 0;
|
||||
while (skipped != n) {
|
||||
long s = skip(n - skipped);
|
||||
if (s < 0)
|
||||
break;
|
||||
if (s == 0)
|
||||
Thread.yield();
|
||||
skipped += s;
|
||||
}
|
||||
return skipped;
|
||||
}
|
||||
|
||||
public long skip(long n) throws IOException {
|
||||
if (avail == 0)
|
||||
return -1;
|
||||
if (n > avail) {
|
||||
long len = stream.skip(avail);
|
||||
if (len != -1)
|
||||
filepointer += len;
|
||||
avail = 0;
|
||||
return len;
|
||||
} else {
|
||||
long ret = stream.skip(n);
|
||||
if (ret == -1) {
|
||||
// will not skip more than
|
||||
long remaining = Math.min(n, avail);
|
||||
while (remaining > 0) {
|
||||
// Some input streams like FileInputStream can return more bytes,
|
||||
// when EOF is reached.
|
||||
long ret = Math.min(stream.skip(remaining), remaining);
|
||||
if (ret == 0) {
|
||||
// EOF or not? we need to check.
|
||||
Thread.yield();
|
||||
if (stream.read() == -1) {
|
||||
avail = 0;
|
||||
break;
|
||||
}
|
||||
ret = 1;
|
||||
} else if (ret < 0) {
|
||||
// the skip should not return negative value, but check it also
|
||||
avail = 0;
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
remaining -= ret;
|
||||
avail -= ret;
|
||||
filepointer += ret;
|
||||
return ret;
|
||||
}
|
||||
return n - remaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() {
|
||||
return (int)avail;
|
||||
}
|
||||
|
||||
public void finish() throws IOException {
|
||||
if (avail != 0) {
|
||||
skipBytes(avail);
|
||||
skip(avail);
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,6 +335,7 @@ public final class RIFFReader extends InputStream {
|
||||
return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
finish();
|
||||
if (this == root)
|
||||
|
@ -29,9 +29,8 @@
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
import javax.sound.sampled.*;
|
||||
|
||||
import com.sun.media.sound.*;
|
||||
import com.sun.media.sound.RIFFReader;
|
||||
import com.sun.media.sound.RIFFWriter;
|
||||
|
||||
public class Skip {
|
||||
|
||||
@ -42,6 +41,11 @@ public class Skip {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
test(false);
|
||||
test(true);
|
||||
}
|
||||
|
||||
private static void test(boolean customStream) throws Exception {
|
||||
RIFFWriter writer = null;
|
||||
RIFFReader reader = null;
|
||||
File tempfile = File.createTempFile("test",".riff");
|
||||
@ -53,7 +57,17 @@ public class Skip {
|
||||
chunk.write((byte)44);
|
||||
writer.close();
|
||||
writer = null;
|
||||
FileInputStream fis = new FileInputStream(tempfile);
|
||||
final FileInputStream fis;
|
||||
if (customStream) {
|
||||
fis = new FileInputStream(tempfile);
|
||||
} else {
|
||||
fis = new FileInputStream(tempfile) {
|
||||
@Override
|
||||
public long skip(long n) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
reader = new RIFFReader(fis);
|
||||
RIFFReader readchunk = reader.nextChunk();
|
||||
reader.skip(1);
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8135160
|
||||
*/
|
||||
public final class EndlessLoopHugeLengthWave {
|
||||
|
||||
// some data wich can cause an endless loop in RiffReader.java
|
||||
private static byte[] headerWAV = {0x52, 0x49, 0x46, 0x46, // RIFF_MAGIC
|
||||
0x7, 0xF, 0xF, 0xF, // fileLength
|
||||
0x57, 0x41, 0x56, 0x45, // waveMagic
|
||||
0x66, 0x6d, 0x74, 0x20, // FMT_MAGIC
|
||||
1, 2, 3, 4, // format
|
||||
3, 0,// wav_type WAVE_FORMAT_IEEE_FLOAT
|
||||
1, 0, // channels
|
||||
1, 1, // sampleRate
|
||||
1, 0, 0, 0, // avgBytesPerSec
|
||||
0, 1, // blockAlign
|
||||
1, 0, // sampleSizeInBits
|
||||
0x64, 0x61, 0x74, 0x61, // DATA_MAGIC
|
||||
};
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
try {
|
||||
AudioSystem.getAudioFileFormat(new ByteArrayInputStream(headerWAV));
|
||||
} catch (final UnsupportedAudioFileException ignored) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user