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 d8b61707 fix(internal/utils): keep byteReader position after failed 
seeks (#1005)
d8b61707 is described below

commit d8b617079e80b195800da271536590077d4e3546
Author: Minh Vu <[email protected]>
AuthorDate: Mon Jul 27 22:01:44 2026 +0200

    fix(internal/utils): keep byteReader position after failed seeks (#1005)
    
    `byteReader` updated its cached position even when the underlying seek
    failed, which could make `Peek` and `Read` disagree about where the
    reader was. `Discard` also returned `io.EOF` when it consumed exactly
    the remaining bytes.
    
    This only updates the cached position after a successful seek and treats
    exact exhaustion as a successful discard. Added focused regressions for
    both behaviors.
    
    Tests: `go test ./internal/utils`
---
 internal/utils/buf_reader.go      |  6 ++++--
 internal/utils/buf_reader_test.go | 22 ++++++++++++++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/internal/utils/buf_reader.go b/internal/utils/buf_reader.go
index 40a7af8d..2d0b5cc9 100644
--- a/internal/utils/buf_reader.go
+++ b/internal/utils/buf_reader.go
@@ -55,7 +55,9 @@ func (r *byteReader) Read(buf []byte) (n int, err error) {
 
 func (r *byteReader) Seek(offset int64, whence int) (pos int64, err error) {
        pos, err = r.r.Seek(offset, whence)
-       r.pos = int(pos)
+       if err == nil {
+               r.pos = int(pos)
+       }
        return
 }
 
@@ -86,7 +88,7 @@ func (r *byteReader) Discard(n int) (int, error) {
                newPos = r.pos + n
        )
 
-       if newPos >= len(r.buf) {
+       if newPos > len(r.buf) {
                newPos = len(r.buf)
                n = newPos - r.pos
                err = io.EOF
diff --git a/internal/utils/buf_reader_test.go 
b/internal/utils/buf_reader_test.go
index e22b80dc..620c6c5b 100644
--- a/internal/utils/buf_reader_test.go
+++ b/internal/utils/buf_reader_test.go
@@ -66,3 +66,25 @@ func TestBufferedReaderPeekReturnsAvailableBytesOnError(t 
*testing.T) {
                t.Fatalf("Peek = %q, want %q", got, "a")
        }
 }
+
+func TestByteReaderSeekErrorPreservesPosition(t *testing.T) {
+       r := NewByteReader([]byte("abc"))
+       buf := make([]byte, 1)
+       if n, err := r.Read(buf); n != 1 || err != nil {
+               t.Fatalf("Read = (%d, %v), want (1, nil)", n, err)
+       }
+
+       if _, err := r.Seek(0, -1); err == nil {
+               t.Fatal("Seek with invalid whence returned nil error")
+       }
+       if got, err := r.Peek(1); err != nil || string(got) != "b" {
+               t.Fatalf("Peek after failed seek = (%q, %v), want (%q, nil)", 
got, err, "b")
+       }
+}
+
+func TestByteReaderDiscardExactRemainingBytes(t *testing.T) {
+       r := NewByteReader([]byte("abc"))
+       if n, err := r.Discard(3); n != 3 || err != nil {
+               t.Fatalf("Discard = (%d, %v), want (3, nil)", n, err)
+       }
+}

Reply via email to