This is an automated email from the ASF dual-hosted git repository.

laskoviymishka pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-go.git


The following commit(s) were added to refs/heads/main by this push:
     new 287c5a83 fix: reject invalid transform widths (#1110)
287c5a83 is described below

commit 287c5a83dcd0b833e687650815fac7148cde4812
Author: Minh Vu <[email protected]>
AuthorDate: Fri May 22 16:43:17 2026 +0200

    fix: reject invalid transform widths (#1110)
    
    ## Summary
    
    - reject invalid `bucket[...]` and `truncate[...]` widths during
    `ParseTransform`
    - treat `Atoi` errors, zero widths, and values above `math.MaxInt32` as
    invalid transforms
    - add parse regression coverage for zero, huge overflow, and
    int32-overflow widths
    
    ## Why
    
    `ParseTransform` previously ignored the `strconv.Atoi` error and
    accepted zero widths. Those invalid transforms could later panic when
    bucket/truncate logic performed modulo by the width. Values larger than
    `math.MaxInt32` are also unsafe because bucket/truncate implementations
    narrow widths through int32-sized paths.
    
    Fixes #1109.
    
    ## Testing
    
    - `go test . -run TestParseTransform`
    - `go test .`
    - `git diff --check`
---
 transforms.go      | 10 ++++++++--
 transforms_test.go |  6 ++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/transforms.go b/transforms.go
index 1f0c7e31..c3179892 100644
--- a/transforms.go
+++ b/transforms.go
@@ -47,7 +47,10 @@ func ParseTransform(s string) (Transform, error) {
                        break
                }
 
-               n, _ := strconv.Atoi(matches[1])
+               n, err := strconv.Atoi(matches[1])
+               if err != nil || n <= 0 || n > math.MaxInt32 {
+                       break
+               }
 
                return BucketTransform{NumBuckets: n}, nil
        case strings.HasPrefix(s, "truncate"):
@@ -56,7 +59,10 @@ func ParseTransform(s string) (Transform, error) {
                        break
                }
 
-               n, _ := strconv.Atoi(matches[1])
+               n, err := strconv.Atoi(matches[1])
+               if err != nil || n <= 0 || n > math.MaxInt32 {
+                       break
+               }
 
                return TruncateTransform{Width: n}, nil
        default:
diff --git a/transforms_test.go b/transforms_test.go
index e624a931..0244f177 100644
--- a/transforms_test.go
+++ b/transforms_test.go
@@ -82,6 +82,12 @@ func TestParseTransform(t *testing.T) {
                {"truncate no val", "truncate[]"},
                {"bucket neg", "bucket[-1]"},
                {"truncate neg", "truncate[-1]"},
+               {"bucket zero", "bucket[0]"},
+               {"truncate zero", "truncate[0]"},
+               {"bucket atoi overflow", 
"bucket[999999999999999999999999999999999999999]"},
+               {"truncate atoi overflow", 
"truncate[999999999999999999999999999999999999999]"},
+               {"bucket int32 overflow", "bucket[4294967296]"},
+               {"truncate int32 overflow", "truncate[4294967296]"},
        }
 
        for _, tt := range errorTests {

Reply via email to