diff options
author | Sergio Giro <sgiro@google.com> | 2016-02-01 18:52:42 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2016-02-01 18:52:42 +0000 |
commit | 9218edabd1ef9852bc2f13115dcadc81b442dd6c (patch) | |
tree | 8229ff72c8cbb06f49dce3a8382930919fa6fc2b /bcpkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java | |
parent | 9b30eb05e5be69d51881a0d1b31e503e97acd784 (diff) | |
parent | 397d32894b89b506dc318e0f83446187c9b76ebe (diff) | |
download | android_external_bouncycastle-9218edabd1ef9852bc2f13115dcadc81b442dd6c.tar.gz android_external_bouncycastle-9218edabd1ef9852bc2f13115dcadc81b442dd6c.tar.bz2 android_external_bouncycastle-9218edabd1ef9852bc2f13115dcadc81b442dd6c.zip |
Merge "Merge remote-tracking branch 'aosp/upstream-master' into merge-152-from-upstream"
Diffstat (limited to 'bcpkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java')
-rw-r--r-- | bcpkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java new file mode 100644 index 0000000..15729a7 --- /dev/null +++ b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/ZlibExpanderProvider.java @@ -0,0 +1,116 @@ +package org.bouncycastle.cms.jcajce; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.InflaterInputStream; + +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.operator.InputExpander; +import org.bouncycastle.operator.InputExpanderProvider; +import org.bouncycastle.util.io.StreamOverflowException; + +public class ZlibExpanderProvider + implements InputExpanderProvider +{ + private final long limit; + + /** + * Base constructor. Create an expander which will not limit the size of any objects expanded in the stream. + */ + public ZlibExpanderProvider() + { + this.limit = -1; + } + + /** + * Create a provider which caps the number of expanded bytes that can be produced when the + * compressed stream is parsed. + * + * @param limit max number of bytes allowed in an expanded stream. + */ + public ZlibExpanderProvider(long limit) + { + this.limit = limit; + } + + public InputExpander get(final AlgorithmIdentifier algorithm) + { + return new InputExpander() + { + public AlgorithmIdentifier getAlgorithmIdentifier() + { + return algorithm; + } + + public InputStream getInputStream(InputStream comIn) + { + InputStream s = new InflaterInputStream(comIn); + if (limit >= 0) + { + s = new LimitedInputStream(s, limit); + } + return s; + } + }; + } + + private static class LimitedInputStream + extends FilterInputStream + { + private long remaining; + + public LimitedInputStream(InputStream input, long limit) + { + super(input); + + this.remaining = limit; + } + + public int read() + throws IOException + { + // Only a single 'extra' byte will ever be read + if (remaining >= 0) + { + int b = super.in.read(); + if (b < 0 || --remaining >= 0) + { + return b; + } + } + + throw new StreamOverflowException("expanded byte limit exceeded"); + } + + public int read(byte[] buf, int off, int len) + throws IOException + { + if (len < 1) + { + // This will give correct exceptions/returns for strange lengths + return super.read(buf, off, len); + } + + if (remaining < 1) + { + // Will either return EOF or throw exception + read(); + return -1; + } + + /* + * Limit the underlying request to 'remaining' bytes. This ensures the + * caller will see the full 'limit' bytes before getting an exception. + * Also, only one extra byte will ever be read. + */ + int actualLen = (remaining > len ? len : (int)remaining); + int numRead = super.in.read(buf, off, actualLen); + if (numRead > 0) + { + remaining -= numRead; + } + return numRead; + } + } +} |