Add flag to disable encryption of uncompressed containers by default

These don't work in the 550 client due to a bug.

Signed-off-by: Graham <gpe@openrs2.dev>
Graham 4 years ago
parent 9aaa095b02
commit 0af11d75c3
  1. 39
      cache/src/main/java/dev/openrs2/cache/Js5Compression.kt
  2. 21
      cache/src/test/java/dev/openrs2/cache/Js5CompressionTest.kt

@ -49,14 +49,39 @@ public object Js5Compression {
} }
} }
public fun compressBest(input: ByteBuf, enableLzma: Boolean = false, key: XteaKey = XteaKey.ZERO): ByteBuf { public fun compressBest(
var best = compress(input.slice(), Js5CompressionType.NONE, key) input: ByteBuf,
enableLzma: Boolean = false,
enableUncompressedEncryption: Boolean = false,
key: XteaKey = XteaKey.ZERO
): ByteBuf {
val types = mutableListOf(Js5CompressionType.BZIP2, Js5CompressionType.GZIP)
if (enableLzma) {
types += Js5CompressionType.LZMA
}
if (enableUncompressedEncryption || key.isZero) {
/*
* The 550 client doesn't strip the 2 byte version trailer before
* passing a group to the XTEA decryption function. This causes the
* last block to be incorrectly decrypt in many cases (depending
* on the length of the group mod the XTEA block size).
*
* This doesn't cause any problems with the client's GZIP/BZIP2
* implementations, as the last block is always part of the trailer
* and the trailer isn't checked. However, it would corrupt the
* last block of an unencrypted group.
*
* TODO(gpe): are there any clients with LZMA support _and_ the
* decryption bug? Could the enableLzma flag be re-used for
* enableNoneWithKey? Or should LZMA also be disabled in clients
* with the decryption bug?
*/
types += Js5CompressionType.NONE
}
var best = compress(input.slice(), types.first(), key)
try { try {
for (type in Js5CompressionType.values()) { for (type in types.drop(1)) {
if (type == Js5CompressionType.NONE || (type == Js5CompressionType.LZMA && !enableLzma)) {
continue
}
compress(input.slice(), type, key).use { output -> compress(input.slice(), type, key).use { output ->
if (output.readableBytes() < best.readableBytes()) { if (output.readableBytes() < best.readableBytes()) {
best.release() best.release()

@ -234,6 +234,27 @@ object Js5CompressionTest {
} }
} }
@Test
fun testUncompressedEncryption() {
Unpooled.wrappedBuffer("OpenRS2".toByteArray()).use { buf ->
Js5Compression.compressBest(buf.slice()).use { compressed ->
assertEquals(Js5CompressionType.NONE.ordinal, compressed.getUnsignedByte(0).toInt())
}
Js5Compression.compressBest(buf.slice(), enableUncompressedEncryption = true).use { compressed ->
assertEquals(Js5CompressionType.NONE.ordinal, compressed.getUnsignedByte(0).toInt())
}
Js5Compression.compressBest(buf.slice(), key = KEY).use { compressed ->
assertNotEquals(Js5CompressionType.NONE.ordinal, compressed.getUnsignedByte(0).toInt())
}
Js5Compression.compressBest(buf.slice(), key = KEY, enableUncompressedEncryption = true).use { compressed ->
assertEquals(Js5CompressionType.NONE.ordinal, compressed.getUnsignedByte(0).toInt())
}
}
}
private fun read(name: String): ByteBuf { private fun read(name: String): ByteBuf {
Js5CompressionTest::class.java.getResourceAsStream("compression/$name").use { input -> Js5CompressionTest::class.java.getResourceAsStream("compression/$name").use { input ->
return Unpooled.wrappedBuffer(input.readAllBytes()) return Unpooled.wrappedBuffer(input.readAllBytes())

Loading…
Cancel
Save