@@ -12,6 +12,7 @@ import "C"
1212import (
1313 "fmt"
1414 "io"
15+ "math"
1516 "strings"
1617 "unsafe"
1718
@@ -553,36 +554,38 @@ func (v *VFSfh) Sync() error {
553554
554555// Seek to an offset
555556func (v * VFSfh ) Seek (offset int64 , whence int ) (int64 , error ) {
556- absOffset := uint64 (offset )
557- if offset <= 0 {
558- absOffset = uint64 (- 1 * offset )
557+ if v .size == nil {
558+ if err := v .fetchAndSetSize (); err != nil {
559+ return - 1 , err
560+ }
559561 }
560- var origin uint64
561562
563+ var origin uint64
562564 switch whence {
563565 case io .SeekStart :
564566 origin = 0
565567 case io .SeekCurrent :
566568 origin = v .offset
567569 case io .SeekEnd :
568- // If the size is empty, fetch it
569- if v .size == nil {
570- err := v .fetchAndSetSize ()
571- if err != nil {
572- return - 1 , err
573- }
574- }
575570 origin = * v .size
576571 default :
577572 return - 1 , fmt .Errorf ("unknown seek whence" )
578573 }
579574
580- if (offset < 0 && absOffset > origin ) ||
581- (offset >= 0 && absOffset > * v .size - origin ) {
582- return - 1 , fmt .Errorf ("invalid offset" )
575+ var newOffset uint64
576+ if offset >= 0 {
577+ newOffset = origin + uint64 (offset )
578+ if newOffset > * v .size {
579+ return - 1 , fmt .Errorf ("invalid offset, attempt to move beyond end of file" )
580+ }
581+ } else {
582+ if offset == math .MinInt64 || uint64 (- offset ) > origin {
583+ return - 1 , fmt .Errorf ("invalid offset, attempt to move before start of file" )
584+ }
585+ newOffset = origin - uint64 (- offset )
583586 }
584587
585- v .offset = uint64 ( int64 ( origin ) + offset )
588+ v .offset = newOffset
586589 return int64 (v .offset ), nil
587590}
588591
0 commit comments