From 5251afd8e7467fb00ae13c0ff6e810cc2b07832a Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Thu, 30 Jul 2026 21:42:40 +0200 Subject: [PATCH] fix(rest): reject blob offsets on non-Puffin delete files Signed-off-by: Minh Vu --- catalog/rest/scan_task_decoder.go | 3 +++ catalog/rest/scan_task_decoder_test.go | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/catalog/rest/scan_task_decoder.go b/catalog/rest/scan_task_decoder.go index 680351b61..70a056512 100644 --- a/catalog/rest/scan_task_decoder.go +++ b/catalog/rest/scan_task_decoder.go @@ -343,6 +343,9 @@ func decodeRESTDeleteFile( if len(wire.EqualityIDs) != 0 { return nil, errors.New("position-deletes file must not carry equality-ids") } + if format != iceberg.PuffinFile && (wire.ContentOffset != nil || wire.ContentSizeInBytes != nil) { + return nil, errors.New("content-offset and content-size-in-bytes are only valid for Puffin deletion vectors") + } if wire.ContentOffset != nil { if *wire.ContentOffset < 0 { return nil, fmt.Errorf("content-offset must be non-negative: %d", *wire.ContentOffset) diff --git a/catalog/rest/scan_task_decoder_test.go b/catalog/rest/scan_task_decoder_test.go index 0b0c82d1a..62be12841 100644 --- a/catalog/rest/scan_task_decoder_test.go +++ b/catalog/rest/scan_task_decoder_test.go @@ -390,6 +390,28 @@ func TestDecodeScanTasksRejectsMalformedPayloads(t *testing.T) { }, want: "must not carry equality-ids", }, + { + name: "non-Puffin position delete with content offset", + mutate: func(w *ScanTasks) { + w.DeleteFiles[0].ContentOffset = int64Ptr(10) + }, + want: "only valid for Puffin deletion vectors", + }, + { + name: "non-Puffin position delete with content size", + mutate: func(w *ScanTasks) { + w.DeleteFiles[0].ContentSizeInBytes = int64Ptr(20) + }, + want: "only valid for Puffin deletion vectors", + }, + { + name: "non-Puffin position delete with blob range", + mutate: func(w *ScanTasks) { + w.DeleteFiles[0].ContentOffset = int64Ptr(10) + w.DeleteFiles[0].ContentSizeInBytes = int64Ptr(20) + }, + want: "only valid for Puffin deletion vectors", + }, { name: "puffin missing blob range", mutate: func(w *ScanTasks) {