github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/ioutil/hardlimitreader.go (about) 1 // Copyright (c) 2015-2023 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 // Package ioutil implements some I/O utility functions which are not covered 19 // by the standard library. 20 package ioutil 21 22 import ( 23 "errors" 24 "io" 25 ) 26 27 // ErrOverread is returned to the reader when the hard limit of HardLimitReader is exceeded. 28 var ErrOverread = errors.New("input provided more bytes than specified") 29 30 // HardLimitReader returns a Reader that reads from r 31 // but returns an error if the source provides more data than allowed. 32 // This means the source *will* be overread unless EOF is returned prior. 33 // The underlying implementation is a *HardLimitedReader. 34 // This will ensure that at most n bytes are returned and EOF is reached. 35 func HardLimitReader(r io.Reader, n int64) io.Reader { return &HardLimitedReader{r, n} } 36 37 // A HardLimitedReader reads from R but limits the amount of 38 // data returned to just N bytes. Each call to Read 39 // updates N to reflect the new amount remaining. 40 // Read returns EOF when N <= 0 or when the underlying R returns EOF. 41 type HardLimitedReader struct { 42 R io.Reader // underlying reader 43 N int64 // max bytes remaining 44 } 45 46 func (l *HardLimitedReader) Read(p []byte) (n int, err error) { 47 if l.N < 0 { 48 return 0, ErrOverread 49 } 50 n, err = l.R.Read(p) 51 l.N -= int64(n) 52 if l.N < 0 { 53 return 0, ErrOverread 54 } 55 return 56 }