This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new cca3d5b6 fix(parquet/compress): honor LZ4 raw destination contract
(#1147)
cca3d5b6 is described below
commit cca3d5b6f1ec88fd1d287536237859a8e13c1e6f
Author: Minh Vu <[email protected]>
AuthorDate: Wed Aug 12 00:10:08 2026 +0200
fix(parquet/compress): honor LZ4 raw destination contract (#1147)
## What
The LZ4 raw codec passed the provided capacity straight to
CompressBlock. Nil or undersized destinations could panic instead of
allocating as promised by Codec.Encode. This allocates the compression
bound when the destination capacity is insufficient.
## Test
- go test ./parquet/compress -count=1
---
parquet/compress/compress_test.go | 15 +++++++++++++++
parquet/compress/lz4_raw.go | 4 ++++
2 files changed, 19 insertions(+)
diff --git a/parquet/compress/compress_test.go
b/parquet/compress/compress_test.go
index a2b9eb28..6483aa65 100644
--- a/parquet/compress/compress_test.go
+++ b/parquet/compress/compress_test.go
@@ -130,6 +130,21 @@ func TestCompressDataOneShot(t *testing.T) {
}
}
+func TestLZ4RawCodecAllocatesDestination(t *testing.T) {
+ codec, err := compress.GetCodec(compress.Codecs.Lz4Raw)
+ assert.NoError(t, err)
+ src := bytes.Repeat([]byte("arrow"), 100)
+
+ for _, dst := range [][]byte{nil, make([]byte, 1)} {
+ compressed := codec.Encode(dst, src)
+ uncompressed := codec.Decode(make([]byte, len(src)), compressed)
+ assert.Equal(t, src, uncompressed)
+ if len(dst) > 0 {
+ assert.NotSame(t, &dst[0], &compressed[0])
+ }
+ }
+}
+
func TestUncompressedCodecAllocatesDestination(t *testing.T) {
codec, err := compress.GetCodec(compress.Codecs.Uncompressed)
assert.NoError(t, err)
diff --git a/parquet/compress/lz4_raw.go b/parquet/compress/lz4_raw.go
index 616f01e3..b069d127 100644
--- a/parquet/compress/lz4_raw.go
+++ b/parquet/compress/lz4_raw.go
@@ -35,6 +35,10 @@ func compressBlock(src, dst []byte) (int, error) {
type lz4RawCodec struct{}
func (c lz4RawCodec) Encode(dst, src []byte) []byte {
+ if bound := c.CompressBound(int64(len(src))); int64(cap(dst)) < bound {
+ dst = make([]byte, int(bound))
+ }
+
n, err := compressBlock(src, dst[:cap(dst)])
if err != nil {
panic(err)