summaryrefslogtreecommitdiffstats
path: root/luni/src/main/java/javax/crypto
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2012-05-21 11:55:20 -0700
committerBrian Carlstrom <bdc@google.com>2012-05-21 13:18:10 -0700
commitc1e57ed799a4fea200144330823f4acbb5330395 (patch)
tree3f8dd40c2064529516548e3d0b62b065dc394f09 /luni/src/main/java/javax/crypto
parent6b3f9499cf6647263b51741e4187a26a54500072 (diff)
downloadlibcore-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.java35
-rw-r--r--luni/src/main/java/javax/crypto/CipherInputStream.java39
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.