diff options
author | Brian Carlstrom <bdc@google.com> | 2012-05-21 11:55:20 -0700 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2012-05-21 13:18:10 -0700 |
commit | c1e57ed799a4fea200144330823f4acbb5330395 (patch) | |
tree | 3f8dd40c2064529516548e3d0b62b065dc394f09 /luni/src/main/java/javax/crypto | |
parent | 6b3f9499cf6647263b51741e4187a26a54500072 (diff) | |
download | libcore-c1e57ed799a4fea200144330823f4acbb5330395.zip libcore-c1e57ed799a4fea200144330823f4acbb5330395.tar.gz libcore-c1e57ed799a4fea200144330823f4acbb5330395.tar.bz2 |
Revert "Revert "Cut down on object allocation in CipherInputStream""
This reverts commit 6b3f9499cf6647263b51741e4187a26a54500072.
Bug: 6523748
Bug: 6478569
Change-Id: Ic422e5fa320995600bdae7a42816652e16b8728b
Diffstat (limited to 'luni/src/main/java/javax/crypto')
-rw-r--r-- | luni/src/main/java/javax/crypto/Cipher.java | 35 | ||||
-rw-r--r-- | luni/src/main/java/javax/crypto/CipherInputStream.java | 39 |
2 files changed, 42 insertions, 32 deletions
diff --git a/luni/src/main/java/javax/crypto/Cipher.java b/luni/src/main/java/javax/crypto/Cipher.java index c8cb601..1dacd46 100644 --- a/luni/src/main/java/javax/crypto/Cipher.java +++ b/luni/src/main/java/javax/crypto/Cipher.java @@ -886,17 +886,25 @@ public class Cipher { if (input == null) { throw new IllegalArgumentException("input == null"); } - if (inputOffset < 0 || inputLen < 0 - || inputLen > input.length - || inputOffset > input.length - inputLen) { - throw new IllegalArgumentException("Incorrect inputOffset/inputLen parameters"); - } + checkInputOffsetAndCount(input.length, inputOffset, inputLen); if (input.length == 0) { return null; } return spiImpl.engineUpdate(input, inputOffset, inputLen); } + private static void checkInputOffsetAndCount(int inputArrayLength, + int inputOffset, + int inputLen) { + if ((inputOffset | inputLen) < 0 + || inputOffset > inputArrayLength + || inputArrayLength - inputOffset < inputLen) { + throw new IllegalArgumentException("input.length=" + inputArrayLength + + "; inputOffset=" + inputOffset + + "; inputLen=" + inputLen); + } + } + /** * Continues a multi-part transformation (encryption or decryption). The * transformed bytes are stored in the {@code output} buffer. @@ -972,12 +980,9 @@ public class Cipher { throw new IllegalArgumentException("output == null"); } if (outputOffset < 0) { - throw new IllegalArgumentException("outputOffset < 0"); - } - if (inputOffset < 0 || inputLen < 0 || inputLen > input.length - || inputOffset > input.length - inputLen) { - throw new IllegalArgumentException("Incorrect inputOffset/inputLen parameters"); + throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset); } + checkInputOffsetAndCount(input.length, inputOffset, inputLen); if (input.length == 0) { return 0; } @@ -1075,7 +1080,7 @@ public class Cipher { throw new IllegalStateException(); } if (outputOffset < 0) { - throw new IllegalArgumentException("outputOffset < 0"); + throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset); } return spiImpl.engineDoFinal(null, 0, 0, output, outputOffset); } @@ -1137,9 +1142,7 @@ public class Cipher { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException(); } - if (inputOffset < 0 || inputLen < 0 || inputOffset + inputLen > input.length) { - throw new IllegalArgumentException("Incorrect inputOffset/inputLen parameters"); - } + checkInputOffsetAndCount(input.length, inputOffset, inputLen); return spiImpl.engineDoFinal(input, inputOffset, inputLen); } @@ -1217,9 +1220,7 @@ public class Cipher { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { throw new IllegalStateException(); } - if (inputOffset < 0 || inputLen < 0 || inputOffset + inputLen > input.length) { - throw new IllegalArgumentException("Incorrect inputOffset/inputLen parameters"); - } + checkInputOffsetAndCount(input.length, inputOffset, inputLen); return spiImpl.engineDoFinal(input, inputOffset, inputLen, output, outputOffset); } diff --git a/luni/src/main/java/javax/crypto/CipherInputStream.java b/luni/src/main/java/javax/crypto/CipherInputStream.java index 4de37db..39dcfda 100644 --- a/luni/src/main/java/javax/crypto/CipherInputStream.java +++ b/luni/src/main/java/javax/crypto/CipherInputStream.java @@ -39,8 +39,9 @@ public class CipherInputStream extends FilterInputStream { private final Cipher cipher; private final byte[] inputBuffer = new byte[I_BUFFER_SIZE]; - private int index; // index of the bytes to return from outputBuffer private byte[] outputBuffer; + private int outputIndex; // index of the first byte to return from outputBuffer + private int outputLength; // count of the bytes to return from outputBuffer private boolean finished; /** @@ -84,27 +85,35 @@ public class CipherInputStream extends FilterInputStream { @Override public int read() throws IOException { if (finished) { - return ((outputBuffer == null) || (index == outputBuffer.length)) - ? -1 - : outputBuffer[index++] & 0xFF; + return (outputIndex == outputLength) ? -1 : outputBuffer[outputIndex++] & 0xFF; } - if ((outputBuffer != null) && (index < outputBuffer.length)) { - return outputBuffer[index++] & 0xFF; + if (outputIndex < outputLength) { + return outputBuffer[outputIndex++] & 0xFF; } - index = 0; - outputBuffer = null; - int byteCount; - while (outputBuffer == null) { - if ((byteCount = in.read(inputBuffer)) == -1) { + outputIndex = 0; + outputLength = 0; + while (outputLength == 0) { + // check output size on each iteration since pending state + // in the cipher can cause this to vary from call to call + int outputSize = cipher.getOutputSize(inputBuffer.length); + if ((outputBuffer == null) || (outputBuffer.length < outputSize)) { + this.outputBuffer = new byte[outputSize]; + } + int byteCount = in.read(inputBuffer); + if (byteCount == -1) { try { - outputBuffer = cipher.doFinal(); + outputLength = cipher.doFinal(outputBuffer, 0); } catch (Exception e) { throw new IOException(e.getMessage()); } finished = true; break; } - outputBuffer = cipher.update(inputBuffer, 0, byteCount); + try { + outputLength = cipher.update(inputBuffer, 0, byteCount, outputBuffer, 0); + } catch (ShortBufferException e) { + throw new AssertionError(e); // should not happen since we sized with getOutputSize + } } return read(); } @@ -113,10 +122,10 @@ public class CipherInputStream extends FilterInputStream { * Reads the next {@code len} bytes from this input stream into buffer * {@code buf} starting at offset {@code off}. * <p> - * if {@code b} is {@code null}, the next {@code len} bytes are read and + * if {@code buf} is {@code null}, the next {@code len} bytes are read and * discarded. * - * @return the number of bytes filled into buffer {@code b}, or {@code -1} + * @return the number of bytes filled into buffer {@code buf}, or {@code -1} * of the of the stream is reached. * @throws IOException * if an error occurs. |