[Client] Fix error in parsing of 'Range' header.
* Result of regexp.FindStringSubmatch must be checked to be not nil. Otherwise it leads to `index out of range`. * Range header regexp is compiled only once to speedup (5x) the header parsing. Signed-off-by: Anton Tiurin <noxiouz@yandex.ru>master
							parent
							
								
									e492579718
								
							
						
					
					
						commit
						9c0519c4ed
					
				| 
						 | 
				
			
			@ -67,6 +67,10 @@ type Client interface {
 | 
			
		|||
	CancelBlobUpload(location string) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	patternRangeHeader = regexp.MustCompile("bytes=0-(\\d+)/(\\d+)")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// New returns a new Client which operates against a registry with the
 | 
			
		||||
// given base endpoint
 | 
			
		||||
// This endpoint should not include /v2/ or any part of the url after this.
 | 
			
		||||
| 
						 | 
				
			
			@ -553,15 +557,18 @@ func (r *clientImpl) CancelBlobUpload(location string) error {
 | 
			
		|||
// parseRangeHeader parses out the offset and length from a returned Range
 | 
			
		||||
// header
 | 
			
		||||
func parseRangeHeader(byteRangeHeader string) (int, int, error) {
 | 
			
		||||
	r := regexp.MustCompile("bytes=0-(\\d+)/(\\d+)")
 | 
			
		||||
	submatches := r.FindStringSubmatch(byteRangeHeader)
 | 
			
		||||
	offset, err := strconv.ParseInt(submatches[1], 10, 0)
 | 
			
		||||
	submatches := patternRangeHeader.FindStringSubmatch(byteRangeHeader)
 | 
			
		||||
	if submatches == nil || len(submatches) < 3 {
 | 
			
		||||
		return 0, 0, fmt.Errorf("Malformed Range header")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	offset, err := strconv.Atoi(submatches[1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, 0, err
 | 
			
		||||
	}
 | 
			
		||||
	length, err := strconv.ParseInt(submatches[2], 10, 0)
 | 
			
		||||
	length, err := strconv.Atoi(submatches[2])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return int(offset), int(length), nil
 | 
			
		||||
	return offset, length, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,37 @@ type testBlob struct {
 | 
			
		|||
	contents []byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRangeHeaderParser(t *testing.T) {
 | 
			
		||||
	const (
 | 
			
		||||
		malformedRangeHeader = "bytes=0-A/C"
 | 
			
		||||
		emptyRangeHeader     = ""
 | 
			
		||||
		rFirst               = 100
 | 
			
		||||
		rSecond              = 200
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		wellformedRangeHeader = fmt.Sprintf("bytes=0-%d/%d", rFirst, rSecond)
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if _, _, err := parseRangeHeader(malformedRangeHeader); err == nil {
 | 
			
		||||
		t.Fatalf("malformedRangeHeader: error expected, got nil")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, _, err := parseRangeHeader(emptyRangeHeader); err == nil {
 | 
			
		||||
		t.Fatalf("emptyRangeHeader: error expected, got nil")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	first, second, err := parseRangeHeader(wellformedRangeHeader)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("wellformedRangeHeader: unexpected error %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if first != rFirst || second != rSecond {
 | 
			
		||||
		t.Fatalf("Range has been parsed unproperly: %d/%d", first, second)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPush(t *testing.T) {
 | 
			
		||||
	name := "hello/world"
 | 
			
		||||
	tag := "sometag"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue