OpenJDK / jdk / jdk10
changeset 26022:45e78fc2279f
7058700: Unexpected exceptions and timeouts in SF2 parser code
Reviewed-by: prr, pchelko
author | serb |
---|---|
date | Thu, 31 Jul 2014 21:09:52 +0100 |
parents | 847033cb0339 |
children | bdcfc40fbce5 |
files | jdk/src/share/classes/com/sun/media/sound/RIFFReader.java jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java |
diffstat | 2 files changed, 50 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/share/classes/com/sun/media/sound/RIFFReader.java Thu Jul 31 23:00:24 2014 +0400 +++ b/jdk/src/share/classes/com/sun/media/sound/RIFFReader.java Thu Jul 31 21:09:52 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2014, 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 @@ -39,21 +39,20 @@ private long filepointer = 0; private final String fourcc; private String riff_type = null; - private long ckSize = 0; + private long ckSize = Integer.MAX_VALUE; private InputStream stream; - private long avail; + private long avail = Integer.MAX_VALUE; private RIFFReader lastiterator = null; public RIFFReader(InputStream stream) throws IOException { - if (stream instanceof RIFFReader) - root = ((RIFFReader)stream).root; - else + if (stream instanceof RIFFReader) { + root = ((RIFFReader) stream).root; + } else { root = this; + } this.stream = stream; - avail = Integer.MAX_VALUE; - ckSize = Integer.MAX_VALUE; // Check for RIFF null paddings, int b; @@ -75,9 +74,12 @@ fourcc[0] = (byte) b; readFully(fourcc, 1, 3); this.fourcc = new String(fourcc, "ascii"); - ckSize = readUnsignedInt(); - - avail = this.ckSize; + final long size = readUnsignedInt(); + if (size > Integer.MAX_VALUE) { + throw new RIFFInvalidDataException("Chunk size too big"); + } + ckSize = size; + avail = size; if (getFormat().equals("RIFF") || getFormat().equals("LIST")) { byte[] format = new byte[4]; @@ -118,19 +120,23 @@ } public int read() throws IOException { - if (avail == 0) + if (avail == 0) { return -1; + } int b = stream.read(); - if (b == -1) + if (b == -1) { + avail = 0; return -1; + } avail--; filepointer++; return b; } public int read(byte[] b, int offset, int len) throws IOException { - if (avail == 0) + if (avail == 0) { return -1; + } if (len > avail) { int rlen = stream.read(b, offset, (int)avail); if (rlen != -1) @@ -139,8 +145,10 @@ return rlen; } else { int ret = stream.read(b, offset, len); - if (ret == -1) + if (ret == -1) { + avail = 0; return -1; + } avail -= ret; filepointer += ret; return ret; @@ -191,8 +199,10 @@ return len; } else { long ret = stream.skip(n); - if (ret == -1) + if (ret == -1) { + avail = 0; return -1; + } avail -= ret; filepointer += ret; return ret; @@ -210,8 +220,13 @@ } // Read ASCII chars from stream - public String readString(int len) throws IOException { - byte[] buff = new byte[len]; + public String readString(final int len) throws IOException { + final byte[] buff; + try { + buff = new byte[len]; + } catch (final OutOfMemoryError oom) { + throw new IOException("Length too big", oom); + } readFully(buff); for (int i = 0; i < buff.length; i++) { if (buff[i] == 0) {
--- a/jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java Thu Jul 31 23:00:24 2014 +0400 +++ b/jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java Thu Jul 31 21:09:52 2014 +0100 @@ -276,6 +276,9 @@ count--; } + if (presets_bagNdx.isEmpty()) { + throw new RIFFInvalidDataException(); + } int offset = presets_bagNdx.get(0); // Offset should be 0 (but just case) for (int i = 0; i < offset; i++) { @@ -360,6 +363,9 @@ count--; } + if (instruments_bagNdx.isEmpty()) { + throw new RIFFInvalidDataException(); + } int offset = instruments_bagNdx.get(0); // Offset should be 0 (but just case) for (int i = 0; i < offset; i++) { @@ -401,6 +407,9 @@ modulator.amount = chunk.readShort(); modulator.amountSourceOperator = chunk.readUnsignedShort(); modulator.transportOperator = chunk.readUnsignedShort(); + if (i < 0 || i >= instruments_splits_gen.size()) { + throw new RIFFInvalidDataException(); + } SF2LayerRegion split = instruments_splits_gen.get(i); if (split != null) split.modulators.add(modulator); @@ -424,7 +433,8 @@ sample.name = chunk.readString(20); long start = chunk.readUnsignedInt(); long end = chunk.readUnsignedInt(); - sample.data = sampleData.subbuffer(start * 2, end * 2, true); + if (sampleData != null) + sample.data = sampleData.subbuffer(start * 2, end * 2, true); if (sampleData24 != null) sample.data24 = sampleData24.subbuffer(start, end, true); /* @@ -462,6 +472,9 @@ int sampleid = split.generators.get( SF2LayerRegion.GENERATOR_SAMPLEID); split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID); + if (sampleid < 0 || sampleid >= samples.size()) { + throw new RIFFInvalidDataException(); + } split.sample = samples.get(sampleid); } else { globalsplit = split; @@ -488,6 +501,9 @@ int instrumentid = split.generators.get( SF2InstrumentRegion.GENERATOR_INSTRUMENT); split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT); + if (instrumentid < 0 || instrumentid >= layers.size()) { + throw new RIFFInvalidDataException(); + } split.layer = layers.get(instrumentid); } else { globalsplit = split;