diff --git a/s2/cmd/s2d/main.go b/s2/cmd/s2d/main.go index 3d152f00f6..ef594356fc 100644 --- a/s2/cmd/s2d/main.go +++ b/s2/cmd/s2d/main.go @@ -278,7 +278,7 @@ Options:`) rs, err := r.ReadSeeker(tailBytes > 0, nil) exitErr(err) if tailBytes > 0 { - _, err = rs.Seek(int64(tailBytes), io.SeekEnd) + _, err = rs.Seek(-int64(tailBytes), io.SeekEnd) } else { _, err = rs.Seek(int64(offset), io.SeekStart) } diff --git a/s2/decode.go b/s2/decode.go index 9e7fce8856..042a329493 100644 --- a/s2/decode.go +++ b/s2/decode.go @@ -699,8 +699,16 @@ func (r *ReadSeeker) Seek(offset int64, whence int) (int64, error) { case io.SeekCurrent: offset += r.blockStart + int64(r.i) case io.SeekEnd: - offset = -offset + if offset > 0 { + return 0, errors.New("seek after end of file") + } + offset = r.index.TotalUncompressed + offset + } + + if offset < 0 { + return 0, errors.New("seek before start of file") } + c, u, err := r.index.Find(offset) if err != nil { return r.blockStart + int64(r.i), err @@ -712,10 +720,6 @@ func (r *ReadSeeker) Seek(offset int64, whence int) (int64, error) { return 0, err } - if offset < 0 { - offset = r.index.TotalUncompressed + offset - } - r.i = r.j // Remove rest of current block. if u < offset { // Forward inside block diff --git a/s2/encode_test.go b/s2/encode_test.go index a1ad5ac591..279c1d961e 100644 --- a/s2/encode_test.go +++ b/s2/encode_test.go @@ -333,7 +333,7 @@ func TestIndex(t *testing.T) { case io.SeekCurrent: toSkip = wantOffset - int64(len(input)/2) case io.SeekEnd: - toSkip = int64(len(input)) - wantOffset + toSkip = -(int64(len(input)) - wantOffset) } gotOffset, err := rs.Seek(toSkip, i) if gotOffset != wantOffset {