github.com/Finschia/finschia-sdk@v0.48.1/internal/os/file.go (about) 1 package os 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 ) 8 9 // ReadFileWithSizeLimit expanded os.ReadFile for checking the file size before reading it 10 func ReadFileWithSizeLimit(name string, sizeLimit int64) ([]byte, error) { 11 f, err := os.Open(name) 12 if err != nil { 13 return nil, err 14 } 15 defer func() { 16 err := f.Close() 17 if err != nil { 18 fmt.Printf("Cannot close the file: %s\n", name) 19 } 20 }() 21 22 var size int 23 if info, err := f.Stat(); err == nil { 24 size64 := info.Size() 25 // Check the file size 26 if size64 > sizeLimit { 27 return nil, fmt.Errorf("the file is too large: %s, size limit over > %d", name, sizeLimit) 28 } 29 if int64(int(size64)) == size64 { 30 size = int(size64) 31 } 32 } 33 size++ // one byte for final read at EOF 34 35 // If a file claims a small size, read at least 512 bytes. 36 // In particular, files in Linux's /proc claim size 0 but 37 // then do not work right if read in small pieces, 38 // so an initial read of 1 byte would not work correctly. 39 if size < 512 { 40 size = 512 41 } 42 43 data := make([]byte, 0, size) 44 for { 45 if len(data) >= cap(data) { 46 d := append(data[:cap(data)], 0) 47 data = d[:len(data)] 48 } 49 n, err := f.Read(data[len(data):cap(data)]) 50 data = data[:len(data)+n] 51 if err != nil { 52 if err == io.EOF { 53 err = nil 54 } 55 return data, err 56 } 57 } 58 }