mirror of https://github.com/jwtk/jjwt.git
Ensured DeflateCompressionCodec could fallback to <= 0.10.6 implementation if encountering an IOException. This allows compressed JWTs created before 0.10.7 to still work. Fixes #536 (#556) (#557)
This commit is contained in:
parent
950e6fbcc7
commit
c38f4af239
|
@ -67,6 +67,9 @@ This patch release:
|
|||
algorithm name instead of the Java Security Standard Algorithm Name of
|
||||
[`RSASSA-PSS`](https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html#signature-algorithms).
|
||||
This release ensures the standard name is used moving forward.
|
||||
|
||||
* Fixes a backwards-compatibility [bug](https://github.com/jwtk/jjwt/issues/536) when parsing compressed JWTs
|
||||
created from 0.10.6 or earlier using the `DEFLATE` compression algorithm.
|
||||
|
||||
### 0.10.7
|
||||
|
||||
|
|
|
@ -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>.
|
||||
|
@ -48,7 +53,40 @@ public class DeflateCompressionCodec extends AbstractCompressionCodec {
|
|||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.parserBuilder().build().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())
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue