Skip to content

LZ4Compression.compress passes total size() where srcLen is expected — silent corruption with Binary.position() > 0 #4317

@ruispereira

Description

@ruispereira

Affected version: 26.4.2 (confirmed still present in 26.5.1)
Component: com.arcadedb.compression.LZ4Compression

Summary

LZ4Compressor.compress(src, srcOff, srcLen, dst, dstOff, maxDestLen) expects the length to compress as the third argument. ArcadeDB passes data.size() (total array length), not decompressedLength = data.size() - data.position(). When data.position() > 0, the compressor reads past the intended slice into unrelated buffer tail. The destination is sized for the correct length, which may also be too small.

The companion decompress(Binary, …) immediately above correctly subtracts position from size; the round-trip therefore silently corrupts the payload (or throws ArrayIndexOutOfBoundsException) whenever any caller passes a non-zero position.

Code

engine/com/arcadedb/compression/LZ4Compression.java:55–61

final int decompressedLength = data.size() - data.position();
final int maxCompressedLength = compressor.maxCompressedLength(decompressedLength);
final byte[] compressed = new byte[maxCompressedLength];
final int compressedLength = compressor.compress(
    data.getContent(),
    data.position(),
    data.size(),                       // ← should be decompressedLength
    compressed, 0, maxCompressedLength);

Impact

Silent data corruption on any compress→decompress round-trip when the source Binary has a non-zero position. Page-level compression callers are the primary at-risk path.

Suggested fix

- compressor.compress(data.getContent(), data.position(), data.size(), …);
+ compressor.compress(data.getContent(), data.position(), decompressedLength, …);

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions