Open-source multiplayer game server compatible with the RuneScape client https://www.openrs2.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
openrs2/cache/src/test/kotlin/org/openrs2/cache/Js5CompressionTest.kt

506 lines
17 KiB

package org.openrs2.cache
import io.netty.buffer.ByteBuf
import io.netty.buffer.Unpooled
import org.openrs2.buffer.copiedBuffer
import org.openrs2.buffer.use
import org.openrs2.crypto.XteaKey
import java.io.IOException
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
object Js5CompressionTest {
private val KEY = XteaKey.fromHex("00112233445566778899AABBCCDDEEFF")
private val INVALID_KEY = XteaKey.fromHex("0123456789ABCDEF0123456789ABCDEF")
@Test
fun testCompressNone() {
read("none.dat").use { expected ->
copiedBuffer("OpenRS2").use { input ->
Js5Compression.compress(input, Js5CompressionType.UNCOMPRESSED).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressNone() {
copiedBuffer("OpenRS2").use { expected ->
read("none.dat").use { input ->
Js5Compression.uncompress(input).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressGzip() {
copiedBuffer("OpenRS2").use { expected ->
Js5Compression.compress(expected.slice(), Js5CompressionType.GZIP).use { compressed ->
Js5Compression.uncompress(compressed).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressGzip() {
copiedBuffer("OpenRS2").use { expected ->
read("gzip.dat").use { input ->
Js5Compression.uncompress(input).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressLargeGzip() {
read("gzip-large.dat").use { input ->
Js5Compression.uncompress(input).use { actual ->
read("large.dat").use { expected ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressBzip2() {
copiedBuffer("OpenRS2").use { expected ->
Js5Compression.compress(expected.slice(), Js5CompressionType.BZIP2).use { compressed ->
Js5Compression.uncompress(compressed).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressBzip2() {
copiedBuffer("OpenRS2").use { expected ->
read("bzip2.dat").use { input ->
Js5Compression.uncompress(input).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressLzma() {
copiedBuffer("OpenRS2").use { expected ->
Js5Compression.compress(expected.slice(), Js5CompressionType.LZMA).use { compressed ->
Js5Compression.uncompress(compressed).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressLzma() {
copiedBuffer("OpenRS2").use { expected ->
read("lzma.dat").use { input ->
Js5Compression.uncompress(input).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressNoneEncrypted() {
read("none-encrypted.dat").use { expected ->
copiedBuffer("OpenRS2".repeat(3)).use { input ->
Js5Compression.compress(input, Js5CompressionType.UNCOMPRESSED, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressNoneEncrypted() {
copiedBuffer("OpenRS2".repeat(3)).use { expected ->
read("none-encrypted.dat").use { input ->
Js5Compression.uncompress(input, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressGzipEncrypted() {
copiedBuffer("OpenRS2").use { expected ->
Js5Compression.compress(expected.slice(), Js5CompressionType.GZIP, KEY).use { compressed ->
Js5Compression.uncompress(compressed, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressGzipEncrypted() {
copiedBuffer("OpenRS2").use { expected ->
read("gzip-encrypted.dat").use { input ->
Js5Compression.uncompress(input, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressBzip2Encrypted() {
copiedBuffer("OpenRS2").use { expected ->
Js5Compression.compress(expected.slice(), Js5CompressionType.BZIP2, KEY).use { compressed ->
Js5Compression.uncompress(compressed, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressBzip2Encrypted() {
copiedBuffer("OpenRS2").use { expected ->
read("bzip2-encrypted.dat").use { input ->
Js5Compression.uncompress(input, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressLzmaEncrypted() {
copiedBuffer("OpenRS2").use { expected ->
Js5Compression.compress(expected.slice(), Js5CompressionType.LZMA, KEY).use { compressed ->
Js5Compression.uncompress(compressed, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressLzmaEncrypted() {
copiedBuffer("OpenRS2").use { expected ->
read("lzma-encrypted.dat").use { input ->
Js5Compression.uncompress(input, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressBest() {
copiedBuffer("OpenRS2".repeat(100)).use { expected ->
val noneLen = Js5Compression.compress(expected.slice(), Js5CompressionType.UNCOMPRESSED).use { compressed ->
compressed.readableBytes()
}
Js5Compression.compressBest(expected.slice()).use { compressed ->
assertNotEquals(Js5CompressionType.UNCOMPRESSED.ordinal, compressed.getUnsignedByte(0).toInt())
assert(compressed.readableBytes() < noneLen)
Js5Compression.uncompress(compressed).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testCompressBestEncrypted() {
copiedBuffer("OpenRS2".repeat(100)).use { expected ->
val noneLen = Js5Compression.compress(expected.slice(), Js5CompressionType.UNCOMPRESSED).use { compressed ->
compressed.readableBytes()
}
Js5Compression.compressBest(expected.slice(), key = KEY).use { compressed ->
assertNotEquals(Js5CompressionType.UNCOMPRESSED.ordinal, compressed.getUnsignedByte(0).toInt())
assert(compressed.readableBytes() < noneLen)
Js5Compression.uncompress(compressed, KEY).use { actual ->
assertEquals(expected, actual)
}
}
}
}
@Test
fun testUncompressedEncryption() {
copiedBuffer("OpenRS2").use { buf ->
Js5Compression.compressBest(buf.slice()).use { compressed ->
assertEquals(Js5CompressionType.UNCOMPRESSED.ordinal, compressed.getUnsignedByte(0).toInt())
}
Js5Compression.compressBest(buf.slice(), enableUncompressedEncryption = true).use { compressed ->
assertEquals(Js5CompressionType.UNCOMPRESSED.ordinal, compressed.getUnsignedByte(0).toInt())
}
Js5Compression.compressBest(buf.slice(), key = KEY).use { compressed ->
assertNotEquals(Js5CompressionType.UNCOMPRESSED.ordinal, compressed.getUnsignedByte(0).toInt())
}
Js5Compression.compressBest(buf.slice(), key = KEY, enableUncompressedEncryption = true).use { compressed ->
assertEquals(Js5CompressionType.UNCOMPRESSED.ordinal, compressed.getUnsignedByte(0).toInt())
}
}
}
@Test
fun testInvalidType() {
read("invalid-type.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFailsWith<IOException> {
Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO)
}
}
}
@Test
fun testInvalidLength() {
read("invalid-length.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFailsWith<IOException> {
Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO)
}
}
}
@Test
fun testInvalidUncompressedLength() {
read("invalid-uncompressed-length.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
}
}
@Test
fun testNoneEof() {
read("none-eof.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed).release()
}
}
}
@Test
fun testBzip2Eof() {
read("bzip2-eof.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
}
}
@Test
fun testGzipEof() {
read("gzip-eof.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
}
}
@Test
fun testLzmaEof() {
read("lzma-eof.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
}
}
@Test
fun testBzip2Corrupt() {
read("bzip2-corrupt.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
}
}
@Test
fun testGzipCorrupt() {
read("gzip-corrupt.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
}
}
@Test
fun testLzmaCorrupt() {
read("lzma-corrupt.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
}
}
@Test
fun testNoneKeyValid() {
read("none.dat").use { compressed ->
assertFalse(Js5Compression.isEncrypted(compressed.slice()))
assertTrue(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), KEY))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), INVALID_KEY))
}
}
@Test
fun testBzip2KeyValid() {
read("bzip2.dat").use { compressed ->
assertFalse(Js5Compression.isEncrypted(compressed.slice()))
assertTrue(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), KEY))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), INVALID_KEY))
}
read("bzip2-encrypted.dat").use { compressed ->
assertTrue(Js5Compression.isEncrypted(compressed.slice()))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
assertTrue(Js5Compression.isKeyValid(compressed.slice(), KEY))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), INVALID_KEY))
}
read("bzip2-invalid-magic.dat").use { compressed ->
assertFalse(Js5Compression.isKeyValid(compressed, XteaKey.ZERO))
}
}
@Test
fun testGzipKeyValid() {
read("gzip.dat").use { compressed ->
assertFalse(Js5Compression.isEncrypted(compressed.slice()))
assertTrue(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), KEY))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), INVALID_KEY))
}
read("gzip-encrypted.dat").use { compressed ->
assertTrue(Js5Compression.isEncrypted(compressed.slice()))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
assertTrue(Js5Compression.isKeyValid(compressed.slice(), KEY))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), INVALID_KEY))
}
read("gzip-invalid-magic.dat").use { compressed ->
assertFalse(Js5Compression.isKeyValid(compressed, XteaKey.ZERO))
}
read("gzip-invalid-method.dat").use { compressed ->
assertFalse(Js5Compression.isKeyValid(compressed, XteaKey.ZERO))
}
}
@Test
fun testLzmaKeyValid() {
read("lzma.dat").use { compressed ->
assertFalse(Js5Compression.isEncrypted(compressed.slice()))
assertTrue(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), KEY))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), INVALID_KEY))
}
read("lzma-encrypted.dat").use { compressed ->
assertTrue(Js5Compression.isEncrypted(compressed.slice()))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO))
assertTrue(Js5Compression.isKeyValid(compressed.slice(), KEY))
assertFalse(Js5Compression.isKeyValid(compressed.slice(), INVALID_KEY))
}
read("lzma-dict-size-negative.dat").use { compressed ->
assertFalse(Js5Compression.isKeyValid(compressed, XteaKey.ZERO))
}
read("lzma-dict-size-larger-than-preset.dat").use { compressed ->
assertFalse(Js5Compression.isKeyValid(compressed, XteaKey.ZERO))
}
read("lzma-invalid-pb.dat").use { compressed ->
assertFalse(Js5Compression.isKeyValid(compressed, XteaKey.ZERO))
}
}
@Test
fun testKeyValidShorterThanTwoBlocks() {
read("shorter-than-two-blocks.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.isKeyValid(compressed, XteaKey.ZERO)
}
}
}
@Test
fun testCompressedUnderflow() {
read("compressed-underflow.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed.slice()).release()
}
assertFailsWith<IOException> {
Js5Compression.isKeyValid(compressed.slice(), XteaKey.ZERO)
}
}
}
@Test
fun testUncompressedOverflow() {
read("uncompressed-overflow.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed).release()
}
}
}
@Test
fun testUncompressedUnderflow() {
read("uncompressed-underflow.dat").use { compressed ->
assertFailsWith<IOException> {
Js5Compression.uncompress(compressed).release()
}
}
}
private fun read(name: String): ByteBuf {
Js5CompressionTest::class.java.getResourceAsStream("compression/$name").use { input ->
return Unpooled.wrappedBuffer(input.readAllBytes())
}
}
}