You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lntop/vendor/gopkg.in/macaroon.v2/packet-v2.go

118 lines
2.8 KiB
Go

package macaroon
import (
"encoding/binary"
"fmt"
)
type fieldType int
// Field constants as used in the binary encoding.
const (
fieldEOS fieldType = 0
fieldLocation fieldType = 1
fieldIdentifier fieldType = 2
fieldVerificationId fieldType = 4
fieldSignature fieldType = 6
)
type packetV2 struct {
// fieldType holds the type of the field.
fieldType fieldType
// data holds the packet's data.
data []byte
}
// parseSectionV2 parses a sequence of packets
// in data. The sequence is terminated by a packet
// with a field type of fieldEOS.
func parseSectionV2(data []byte) ([]byte, []packetV2, error) {
prevFieldType := fieldType(-1)
var packets []packetV2
for {
if len(data) == 0 {
return nil, nil, fmt.Errorf("section extends past end of buffer")
}
rest, p, err := parsePacketV2(data)
if err != nil {
return nil, nil, err
}
if p.fieldType == fieldEOS {
return rest, packets, nil
}
if p.fieldType <= prevFieldType {
return nil, nil, fmt.Errorf("fields out of order")
}
packets = append(packets, p)
prevFieldType = p.fieldType
data = rest
}
}
// parsePacketV2 parses a V2 data package at the start
// of the given data.
// The format of a packet is as follows:
//
// fieldType(varint) payloadLen(varint) data[payloadLen bytes]
//
// apart from fieldEOS which has no payloadLen or data (it's
// a single zero byte).
func parsePacketV2(data []byte) ([]byte, packetV2, error) {
data, ft, err := parseVarint(data)
if err != nil {
return nil, packetV2{}, err
}
p := packetV2{
fieldType: fieldType(ft),
}
if p.fieldType == fieldEOS {
return data, p, nil
}
data, payloadLen, err := parseVarint(data)
if err != nil {
return nil, packetV2{}, err
}
if payloadLen > len(data) {
return nil, packetV2{}, fmt.Errorf("field data extends past end of buffer")
}
p.data = data[0:payloadLen]
return data[payloadLen:], p, nil
}
// parseVarint parses the variable-length integer
// at the start of the given data and returns rest
// of the buffer and the number.
func parseVarint(data []byte) ([]byte, int, error) {
val, n := binary.Uvarint(data)
if n > 0 {
if val > 0x7fffffff {
return nil, 0, fmt.Errorf("varint value out of range")
}
return data[n:], int(val), nil
}
if n == 0 {
return nil, 0, fmt.Errorf("varint value extends past end of buffer")
}
return nil, 0, fmt.Errorf("varint value out of range")
}
func appendPacketV2(data []byte, p packetV2) []byte {
data = appendVarint(data, int(p.fieldType))
if p.fieldType != fieldEOS {
data = appendVarint(data, len(p.data))
data = append(data, p.data...)
}
return data
}
func appendEOSV2(data []byte) []byte {
return append(data, 0)
}
func appendVarint(data []byte, x int) []byte {
var buf [binary.MaxVarintLen32]byte
n := binary.PutUvarint(buf[:], uint64(x))
return append(data, buf[:n]...)
}