Strictly enforce packet size limits for incoming compressed packets
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package com.velocitypowered.natives.compression;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
class CompressorUtils {
|
||||
/**
|
||||
* The default preferred output buffer size for zlib.
|
||||
*/
|
||||
static final int ZLIB_BUFFER_SIZE = 8192;
|
||||
|
||||
/**
|
||||
* Ensures that the buffer does not go over {@code max}.
|
||||
* @param buf the buffer for check
|
||||
* @param max the maximum size for the buffer
|
||||
* @throws DataFormatException if the buffer becomes too bug
|
||||
*/
|
||||
static void ensureMaxSize(ByteBuf buf, int max) throws DataFormatException {
|
||||
int len = buf.readableBytes();
|
||||
if (len > max) {
|
||||
throw new DataFormatException("Got too much data (" + len + " > " + max + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private CompressorUtils() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package com.velocitypowered.natives.compression;
|
||||
|
||||
import static com.velocitypowered.natives.util.NativeConstants.ZLIB_BUFFER_SIZE;
|
||||
import static com.velocitypowered.natives.compression.CompressorUtils.ZLIB_BUFFER_SIZE;
|
||||
import static com.velocitypowered.natives.compression.CompressorUtils.ensureMaxSize;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -24,7 +25,7 @@ public class JavaVelocityCompressor implements VelocityCompressor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException {
|
||||
public void inflate(ByteBuf source, ByteBuf destination, int max) throws DataFormatException {
|
||||
ensureNotDisposed();
|
||||
|
||||
if (source.hasArray()) {
|
||||
@@ -37,6 +38,7 @@ public class JavaVelocityCompressor implements VelocityCompressor {
|
||||
}
|
||||
|
||||
while (!inflater.finished()) {
|
||||
ensureMaxSize(destination, max);
|
||||
int read = inflater.inflate(buf);
|
||||
destination.writeBytes(buf, 0, read);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package com.velocitypowered.natives.compression;
|
||||
|
||||
import static com.velocitypowered.natives.util.NativeConstants.ZLIB_BUFFER_SIZE;
|
||||
import static com.velocitypowered.natives.compression.CompressorUtils.ZLIB_BUFFER_SIZE;
|
||||
import static com.velocitypowered.natives.compression.CompressorUtils.ensureMaxSize;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -22,18 +23,19 @@ public class NativeVelocityCompressor implements VelocityCompressor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException {
|
||||
public void inflate(ByteBuf source, ByteBuf destination, int max) throws DataFormatException {
|
||||
ensureNotDisposed();
|
||||
source.memoryAddress();
|
||||
destination.memoryAddress();
|
||||
|
||||
while (!inflate.finished && source.isReadable()) {
|
||||
if (!destination.isWritable()) {
|
||||
ensureMaxSize(destination, max);
|
||||
destination.ensureWritable(ZLIB_BUFFER_SIZE);
|
||||
}
|
||||
int produced = inflate.process(inflateCtx, source.memoryAddress() + source.readerIndex(),
|
||||
source.readableBytes(),
|
||||
destination.memoryAddress() + destination.writerIndex(), destination.writableBytes());
|
||||
source.readableBytes(), destination.memoryAddress() + destination.writerIndex(),
|
||||
destination.writableBytes());
|
||||
source.readerIndex(source.readerIndex() + inflate.consumed);
|
||||
destination.writerIndex(destination.writerIndex() + produced);
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import java.util.zip.DataFormatException;
|
||||
* Provides an interface to inflate and deflate {@link ByteBuf}s using zlib.
|
||||
*/
|
||||
public interface VelocityCompressor extends Disposable, Native {
|
||||
void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
|
||||
void inflate(ByteBuf source, ByteBuf destination, int max) throws DataFormatException;
|
||||
|
||||
void deflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
|
||||
}
|
||||
|
@@ -70,7 +70,7 @@ class VelocityCompressorTest {
|
||||
|
||||
try {
|
||||
compressor.deflate(source, dest);
|
||||
compressor.inflate(dest, decompressed);
|
||||
compressor.inflate(dest, decompressed, Integer.MAX_VALUE);
|
||||
source.readerIndex(0);
|
||||
assertTrue(ByteBufUtil.equals(source, decompressed));
|
||||
} finally {
|
||||
|
Reference in New Issue
Block a user