Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensured DeflateCompressionCodec could fallback to <= 0.10.6 implementation #556

Merged
merged 1 commit into from
Feb 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@
*/
package io.jsonwebtoken.impl.compression;

import io.jsonwebtoken.lang.Objects;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import java.util.zip.InflaterOutputStream;

/**
* Codec implementing the <a href="https://en.wikipedia.org/wiki/DEFLATE">deflate compression algorithm</a>.
Expand Down Expand Up @@ -48,7 +53,40 @@ protected byte[] doCompress(byte[] payload) throws IOException {
}

@Override
protected byte[] doDecompress(byte[] compressed) throws IOException {
return readAndClose(new InflaterInputStream(new ByteArrayInputStream(compressed)));
protected byte[] doDecompress(final byte[] compressed) throws IOException {
try {
return readAndClose(new InflaterInputStream(new ByteArrayInputStream(compressed)));
} catch (IOException e1) {
try {
return doDecompressBackCompat(compressed);
} catch (IOException e2) {
throw e1; //retain/report original exception
}
}
}

/**
* This implementation was in 0.10.6 and earlier - it will be used as a fallback for backwards compatibility if
* {@link #readAndClose(InputStream)} fails per <a href="https://github.com/jwtk/jjwt/issues/536">Issue 536</a>.
*
* @param compressed the compressed byte array
* @return decompressed bytes
* @throws IOException if unable to decompress using the 0.10.6 and earlier logic
* @since 0.10.8
*/
// package protected on purpose
byte[] doDecompressBackCompat(byte[] compressed) throws IOException {
InflaterOutputStream inflaterOutputStream = null;
ByteArrayOutputStream decompressedOutputStream = null;

try {
decompressedOutputStream = new ByteArrayOutputStream();
inflaterOutputStream = new InflaterOutputStream(decompressedOutputStream);
inflaterOutputStream.write(compressed);
inflaterOutputStream.flush();
return decompressedOutputStream.toByteArray();
} finally {
Objects.nullSafeClose(decompressedOutputStream, inflaterOutputStream);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.jsonwebtoken.impl.compression

import io.jsonwebtoken.CompressionException
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.io.Decoders
import org.junit.Test

import static org.junit.Assert.assertNotSame

/**
* @since 0.10.8
*/
class DeflateCompressionCodecTest {

/**
* Test case for <a href="https://github.com/jwtk/jjwt/issues/536">Issue 536</a>.
*/
@Test
void testBackwardsCompatibility_0_10_6() {
final String jwtFrom0106 = 'eyJhbGciOiJub25lIiwiemlwIjoiREVGIn0.eNqqVsosLlayUspNVdJRKi5NAjJLi1OLgJzMxBIlK0sTMzMLEwsDAx2l1IoCJSsTQwMjExOQQC0AAAD__w.'
Jwts.parser().parseClaimsJwt(jwtFrom0106) // no exception should be thrown
}

/**
* Test to ensure that, even if the backwards-compatibility fallback method throws an exception, that the first
* one is retained/re-thrown to reflect the correct/expected implementation.
*/
@Test
void testBackwardsCompatibilityRetainsFirstIOException() {

final String compressedFrom0_10_6 = 'eNqqVsosLlayUspNVdJRKi5NAjJLi1OLgJzMxBIlK0sTMzMLEwsDAx2l1IoCJSsTQwMjExOQQC0AAAD__w'
byte[] invalid = Decoders.BASE64URL.decode(compressedFrom0_10_6)

IOException unexpected = new IOException("foo")

def codec = new DeflateCompressionCodec() {
@Override
byte[] doDecompressBackCompat(byte[] compressed) throws IOException {
throw unexpected
}
}

try {
codec.decompress(invalid)
} catch (CompressionException ce) {
assertNotSame(unexpected, ce.getCause())
}
}
}