diff options
Diffstat (limited to 'vendor/github.com/docker')
| -rw-r--r-- | vendor/github.com/docker/go-units/size.go | 70 | 
1 files changed, 58 insertions, 12 deletions
diff --git a/vendor/github.com/docker/go-units/size.go b/vendor/github.com/docker/go-units/size.go index 85f6ab071..c245a8951 100644 --- a/vendor/github.com/docker/go-units/size.go +++ b/vendor/github.com/docker/go-units/size.go @@ -2,7 +2,6 @@ package units  import (  	"fmt" -	"regexp"  	"strconv"  	"strings"  ) @@ -26,16 +25,17 @@ const (  	PiB = 1024 * TiB  ) -type unitMap map[string]int64 +type unitMap map[byte]int64  var ( -	decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB} -	binaryMap  = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB} -	sizeRegex  = regexp.MustCompile(`^(\d+(\.\d+)*) ?([kKmMgGtTpP])?[iI]?[bB]?$`) +	decimalMap = unitMap{'k': KB, 'm': MB, 'g': GB, 't': TB, 'p': PB} +	binaryMap  = unitMap{'k': KiB, 'm': MiB, 'g': GiB, 't': TiB, 'p': PiB}  ) -var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} -var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} +var ( +	decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} +	binaryAbbrs  = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} +)  func getSizeAndUnit(size float64, base float64, _map []string) (float64, string) {  	i := 0 @@ -89,20 +89,66 @@ func RAMInBytes(size string) (int64, error) {  // Parses the human-readable size string into the amount it represents.  func parseSize(sizeStr string, uMap unitMap) (int64, error) { -	matches := sizeRegex.FindStringSubmatch(sizeStr) -	if len(matches) != 4 { +	// TODO: rewrite to use strings.Cut if there's a space +	// once Go < 1.18 is deprecated. +	sep := strings.LastIndexAny(sizeStr, "01234567890. ") +	if sep == -1 { +		// There should be at least a digit.  		return -1, fmt.Errorf("invalid size: '%s'", sizeStr)  	} +	var num, sfx string +	if sizeStr[sep] != ' ' { +		num = sizeStr[:sep+1] +		sfx = sizeStr[sep+1:] +	} else { +		// Omit the space separator. +		num = sizeStr[:sep] +		sfx = sizeStr[sep+1:] +	} -	size, err := strconv.ParseFloat(matches[1], 64) +	size, err := strconv.ParseFloat(num, 64)  	if err != nil {  		return -1, err  	} +	// Backward compatibility: reject negative sizes. +	if size < 0 { +		return -1, fmt.Errorf("invalid size: '%s'", sizeStr) +	} + +	if len(sfx) == 0 { +		return int64(size), nil +	} -	unitPrefix := strings.ToLower(matches[3]) -	if mul, ok := uMap[unitPrefix]; ok { +	// Process the suffix. + +	if len(sfx) > 3 { // Too long. +		goto badSuffix +	} +	sfx = strings.ToLower(sfx) +	// Trivial case: b suffix. +	if sfx[0] == 'b' { +		if len(sfx) > 1 { // no extra characters allowed after b. +			goto badSuffix +		} +		return int64(size), nil +	} +	// A suffix from the map. +	if mul, ok := uMap[sfx[0]]; ok {  		size *= float64(mul) +	} else { +		goto badSuffix +	} + +	// The suffix may have extra "b" or "ib" (e.g. KiB or MB). +	switch { +	case len(sfx) == 2 && sfx[1] != 'b': +		goto badSuffix +	case len(sfx) == 3 && sfx[1:] != "ib": +		goto badSuffix  	}  	return int64(size), nil + +badSuffix: +	return -1, fmt.Errorf("invalid suffix: '%s'", sfx)  }  | 
