Skip to content

Commit

Permalink
Prevent JVM crash when buffer too small
Browse files Browse the repository at this point in the history
  • Loading branch information
findepi committed Apr 12, 2022
1 parent ebcf1ed commit 89892d7
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@
<version>0.4</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/io/airlift/compress/lz4/Lz4Compressor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import static io.airlift.compress.lz4.Lz4RawCompressor.MAX_TABLE_SIZE;
import static io.airlift.compress.lz4.UnsafeUtil.getAddress;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;

/**
Expand All @@ -39,6 +41,9 @@ public int maxCompressedLength(int uncompressedSize)
@Override
public int compress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
{
verifyRange(input, inputOffset, inputLength);
verifyRange(output, outputOffset, maxOutputLength);

long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;

Expand Down Expand Up @@ -109,4 +114,12 @@ else if (output.hasArray()) {
}
}
}

private static void verifyRange(byte[] data, int offset, int length)
{
requireNonNull(data, "data is null");
if (offset < 0 || length < 0 || offset + length > data.length) {
throw new IllegalArgumentException(format("Invalid offset or length (%s, %s) in array of length %s", offset, length, data.length));
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/io/airlift/compress/lz4/Lz4Decompressor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.nio.ByteBuffer;

import static io.airlift.compress.lz4.UnsafeUtil.getAddress;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;

public class Lz4Decompressor
Expand All @@ -29,6 +31,9 @@ public class Lz4Decompressor
public int decompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
throws MalformedInputException
{
verifyRange(input, inputOffset, inputLength);
verifyRange(output, outputOffset, maxOutputLength);

long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long inputLimit = inputAddress + inputLength;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;
Expand Down Expand Up @@ -95,4 +100,12 @@ else if (output.hasArray()) {
}
}
}

private static void verifyRange(byte[] data, int offset, int length)
{
requireNonNull(data, "data is null");
if (offset < 0 || length < 0 || offset + length > data.length) {
throw new IllegalArgumentException(format("Invalid offset or length (%s, %s) in array of length %s", offset, length, data.length));
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/io/airlift/compress/lzo/LzoCompressor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import static io.airlift.compress.lzo.LzoRawCompressor.MAX_TABLE_SIZE;
import static io.airlift.compress.lzo.UnsafeUtil.getAddress;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;

/**
Expand All @@ -39,6 +41,9 @@ public int maxCompressedLength(int uncompressedSize)
@Override
public int compress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
{
verifyRange(input, inputOffset, inputLength);
verifyRange(output, outputOffset, maxOutputLength);

long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;

Expand Down Expand Up @@ -109,4 +114,12 @@ else if (output.hasArray()) {
}
}
}

private static void verifyRange(byte[] data, int offset, int length)
{
requireNonNull(data, "data is null");
if (offset < 0 || length < 0 || offset + length > data.length) {
throw new IllegalArgumentException(format("Invalid offset or length (%s, %s) in array of length %s", offset, length, data.length));
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/io/airlift/compress/lzo/LzoDecompressor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.nio.ByteBuffer;

import static io.airlift.compress.lzo.UnsafeUtil.getAddress;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;

public class LzoDecompressor
Expand All @@ -29,6 +31,9 @@ public class LzoDecompressor
public int decompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
throws MalformedInputException
{
verifyRange(input, inputOffset, inputLength);
verifyRange(output, outputOffset, maxOutputLength);

long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long inputLimit = inputAddress + inputLength;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;
Expand Down Expand Up @@ -95,4 +100,12 @@ else if (output.hasArray()) {
}
}
}

private static void verifyRange(byte[] data, int offset, int length)
{
requireNonNull(data, "data is null");
if (offset < 0 || length < 0 || offset + length > data.length) {
throw new IllegalArgumentException(format("Invalid offset or length (%s, %s) in array of length %s", offset, length, data.length));
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/io/airlift/compress/snappy/SnappyCompressor.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.nio.ByteBuffer;

import static io.airlift.compress.snappy.UnsafeUtil.getAddress;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;

public class SnappyCompressor
Expand All @@ -35,6 +37,9 @@ public int maxCompressedLength(int uncompressedSize)
@Override
public int compress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
{
verifyRange(input, inputOffset, inputLength);
verifyRange(output, outputOffset, maxOutputLength);

long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long inputLimit = inputAddress + inputLength;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;
Expand Down Expand Up @@ -107,4 +112,12 @@ else if (output.hasArray()) {
}
}
}

private static void verifyRange(byte[] data, int offset, int length)
{
requireNonNull(data, "data is null");
if (offset < 0 || length < 0 || offset + length > data.length) {
throw new IllegalArgumentException(format("Invalid offset or length (%s, %s) in array of length %s", offset, length, data.length));
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/io/airlift/compress/snappy/SnappyDecompressor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.nio.ByteBuffer;

import static io.airlift.compress.snappy.UnsafeUtil.getAddress;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;

public class SnappyDecompressor
Expand All @@ -37,6 +39,9 @@ public static int getUncompressedLength(byte[] compressed, int compressedOffset)
public int decompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
throws MalformedInputException
{
verifyRange(input, inputOffset, inputLength);
verifyRange(output, outputOffset, maxOutputLength);

long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long inputLimit = inputAddress + inputLength;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;
Expand Down Expand Up @@ -103,4 +108,12 @@ else if (output.hasArray()) {
}
}
}

private static void verifyRange(byte[] data, int offset, int length)
{
requireNonNull(data, "data is null");
if (offset < 0 || length < 0 || offset + length > data.length) {
throw new IllegalArgumentException(format("Invalid offset or length (%s, %s) in array of length %s", offset, length, data.length));
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/io/airlift/compress/zstd/ZstdCompressor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import static io.airlift.compress.zstd.Constants.MAX_BLOCK_SIZE;
import static io.airlift.compress.zstd.UnsafeUtil.getAddress;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;

public class ZstdCompressor
Expand All @@ -40,6 +42,9 @@ public int maxCompressedLength(int uncompressedSize)
@Override
public int compress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
{
verifyRange(input, inputOffset, inputLength);
verifyRange(output, outputOffset, maxOutputLength);

long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;

Expand Down Expand Up @@ -110,4 +115,12 @@ else if (output.hasArray()) {
}
}
}

private static void verifyRange(byte[] data, int offset, int length)
{
requireNonNull(data, "data is null");
if (offset < 0 || length < 0 || offset + length > data.length) {
throw new IllegalArgumentException(format("Invalid offset or length (%s, %s) in array of length %s", offset, length, data.length));
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/io/airlift/compress/zstd/ZstdDecompressor.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.nio.ByteBuffer;

import static io.airlift.compress.zstd.UnsafeUtil.getAddress;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;

public class ZstdDecompressor
Expand All @@ -31,6 +33,9 @@ public class ZstdDecompressor
public int decompress(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int maxOutputLength)
throws MalformedInputException
{
verifyRange(input, inputOffset, inputLength);
verifyRange(output, outputOffset, maxOutputLength);

long inputAddress = ARRAY_BYTE_BASE_OFFSET + inputOffset;
long inputLimit = inputAddress + inputLength;
long outputAddress = ARRAY_BYTE_BASE_OFFSET + outputOffset;
Expand Down Expand Up @@ -103,4 +108,12 @@ public static long getDecompressedSize(byte[] input, int offset, int length)
int baseAddress = ARRAY_BYTE_BASE_OFFSET + offset;
return ZstdFrameDecompressor.getDecompressedSize(input, baseAddress, baseAddress + length);
}

private static void verifyRange(byte[] data, int offset, int length)
{
requireNonNull(data, "data is null");
if (offset < 0 || length < 0 || offset + length > data.length) {
throw new IllegalArgumentException(format("Invalid offset or length (%s, %s) in array of length %s", offset, length, data.length));
}
}
}
Loading

0 comments on commit 89892d7

Please sign in to comment.