summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-asn1-ber
diff options
context:
space:
mode:
authorWim <wim@42.be>2020-10-19 23:40:00 +0200
committerGitHub <noreply@github.com>2020-10-19 23:40:00 +0200
commit075a84427f6332aab707d283ad770d69f8816032 (patch)
tree0ff9f56a057919f3fe968e57f6f0b1c0d1f85078 /vendor/github.com/go-asn1-ber
parent950f2759bd2b20aa0bdedc3dc9a74d0dafb606d8 (diff)
downloadmatterbridge-msglm-075a84427f6332aab707d283ad770d69f8816032.tar.gz
matterbridge-msglm-075a84427f6332aab707d283ad770d69f8816032.tar.bz2
matterbridge-msglm-075a84427f6332aab707d283ad770d69f8816032.zip
Update vendor (#1265)
Diffstat (limited to 'vendor/github.com/go-asn1-ber')
-rw-r--r--vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml73
-rw-r--r--vendor/github.com/go-asn1-ber/asn1-ber/ber.go198
-rw-r--r--vendor/github.com/go-asn1-ber/asn1-ber/content_int.go2
-rw-r--r--vendor/github.com/go-asn1-ber/asn1-ber/generalizedTime.go105
-rw-r--r--vendor/github.com/go-asn1-ber/asn1-ber/header.go19
-rw-r--r--vendor/github.com/go-asn1-ber/asn1-ber/length.go12
-rw-r--r--vendor/github.com/go-asn1-ber/asn1-ber/real.go157
-rw-r--r--vendor/github.com/go-asn1-ber/asn1-ber/util.go2
8 files changed, 461 insertions, 107 deletions
diff --git a/vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml b/vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml
index 4ad2067b..8bffb901 100644
--- a/vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml
+++ b/vendor/github.com/go-asn1-ber/asn1-ber/.travis.yml
@@ -1,38 +1,39 @@
language: go
-matrix:
- include:
- - go: 1.2.x
- env: GOOS=linux GOARCH=amd64
- - go: 1.2.x
- env: GOOS=linux GOARCH=386
- - go: 1.2.x
- env: GOOS=windows GOARCH=amd64
- - go: 1.2.x
- env: GOOS=windows GOARCH=386
- - go: 1.3.x
- - go: 1.4.x
- - go: 1.5.x
- - go: 1.6.x
- - go: 1.7.x
- - go: 1.8.x
- - go: 1.9.x
- - go: 1.10.x
- - go: 1.11.x
- - go: 1.12.x
- - go: 1.13.x
- env: GOOS=linux GOARCH=amd64
- - go: 1.13.x
- env: GOOS=linux GOARCH=386
- - go: 1.13.x
- env: GOOS=windows GOARCH=amd64
- - go: 1.13.x
- env: GOOS=windows GOARCH=386
- - go: tip
-go_import_path: gopkg.in/asn-ber.v1
-install:
- - go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v
- - go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v
- - go get code.google.com/p/go.tools/cmd/cover || go get golang.org/x/tools/cmd/cover
- - go build -v ./...
+
+go:
+ - 1.2.x
+ - 1.6.x
+ - 1.9.x
+ - 1.10.x
+ - 1.11.x
+ - 1.12.x
+ - 1.14.x
+ - tip
+
+os:
+ - linux
+
+arch:
+ - amd64
+
+dist: xenial
+
+env:
+ - GOARCH=amd64
+
+jobs:
+ include:
+ - os: windows
+ go: 1.14.x
+ - os: osx
+ go: 1.14.x
+ - os: linux
+ go: 1.14.x
+ arch: arm64
+ - os: linux
+ go: 1.14.x
+ env:
+ - GOARCH=386
+
script:
- - go test -v -cover ./... || go test -v ./...
+ - go test -v -cover ./... || go test -v ./...
diff --git a/vendor/github.com/go-asn1-ber/asn1-ber/ber.go b/vendor/github.com/go-asn1-ber/asn1-ber/ber.go
index 1e186cb8..4fd7a66e 100644
--- a/vendor/github.com/go-asn1-ber/asn1-ber/ber.go
+++ b/vendor/github.com/go-asn1-ber/asn1-ber/ber.go
@@ -8,6 +8,8 @@ import (
"math"
"os"
"reflect"
+ "time"
+ "unicode/utf8"
)
// MaxPacketLengthBytes specifies the maximum allowed packet size when calling ReadPacket or DecodePacket. Set to 0 for
@@ -143,20 +145,20 @@ var TypeMap = map[Type]string{
TypeConstructed: "Constructed",
}
-var Debug bool = false
+var Debug = false
func PrintBytes(out io.Writer, buf []byte, indent string) {
- data_lines := make([]string, (len(buf)/30)+1)
- num_lines := make([]string, (len(buf)/30)+1)
+ dataLines := make([]string, (len(buf)/30)+1)
+ numLines := make([]string, (len(buf)/30)+1)
for i, b := range buf {
- data_lines[i/30] += fmt.Sprintf("%02x ", b)
- num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
+ dataLines[i/30] += fmt.Sprintf("%02x ", b)
+ numLines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
}
- for i := 0; i < len(data_lines); i++ {
- out.Write([]byte(indent + data_lines[i] + "\n"))
- out.Write([]byte(indent + num_lines[i] + "\n\n"))
+ for i := 0; i < len(dataLines); i++ {
+ _, _ = out.Write([]byte(indent + dataLines[i] + "\n"))
+ _, _ = out.Write([]byte(indent + numLines[i] + "\n\n"))
}
}
@@ -169,20 +171,20 @@ func PrintPacket(p *Packet) {
}
func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
- indent_str := ""
+ indentStr := ""
- for len(indent_str) != indent {
- indent_str += " "
+ for len(indentStr) != indent {
+ indentStr += " "
}
- class_str := ClassMap[p.ClassType]
+ classStr := ClassMap[p.ClassType]
- tagtype_str := TypeMap[p.TagType]
+ tagTypeStr := TypeMap[p.TagType]
- tag_str := fmt.Sprintf("0x%02X", p.Tag)
+ tagStr := fmt.Sprintf("0x%02X", p.Tag)
if p.ClassType == ClassUniversal {
- tag_str = tagMap[p.Tag]
+ tagStr = tagMap[p.Tag]
}
value := fmt.Sprint(p.Value)
@@ -192,10 +194,10 @@ func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
description = p.Description + ": "
}
- fmt.Fprintf(out, "%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value)
+ _, _ = fmt.Fprintf(out, "%s%s(%s, %s, %s) Len=%d %q\n", indentStr, description, classStr, tagTypeStr, tagStr, p.Data.Len(), value)
if printBytes {
- PrintBytes(out, p.Bytes(), indent_str)
+ PrintBytes(out, p.Bytes(), indentStr)
}
for _, child := range p.Children {
@@ -203,7 +205,7 @@ func printPacket(out io.Writer, p *Packet, indent int, printBytes bool) {
}
}
-// ReadPacket reads a single Packet from the reader
+// ReadPacket reads a single Packet from the reader.
func ReadPacket(reader io.Reader) (*Packet, error) {
p, _, err := readPacket(reader)
if err != nil {
@@ -239,7 +241,7 @@ func encodeInteger(i int64) []byte {
var j int
for ; n > 0; n-- {
- out[j] = (byte(i >> uint((n-1)*8)))
+ out[j] = byte(i >> uint((n-1)*8))
j++
}
@@ -271,7 +273,7 @@ func DecodePacket(data []byte) *Packet {
}
// DecodePacketErr decodes the given bytes into a single Packet
-// If a decode error is encountered, nil is returned
+// If a decode error is encountered, nil is returned.
func DecodePacketErr(data []byte) (*Packet, error) {
p, _, err := readPacket(bytes.NewBuffer(data))
if err != nil {
@@ -280,7 +282,7 @@ func DecodePacketErr(data []byte) (*Packet, error) {
return p, nil
}
-// readPacket reads a single Packet from the reader, returning the number of bytes read
+// readPacket reads a single Packet from the reader, returning the number of bytes read.
func readPacket(reader io.Reader) (*Packet, int, error) {
identifier, length, read, err := readHeader(reader)
if err != nil {
@@ -342,7 +344,7 @@ func readPacket(reader io.Reader) (*Packet, int, error) {
if MaxPacketLengthBytes > 0 && int64(length) > MaxPacketLengthBytes {
return nil, read, fmt.Errorf("length %d greater than maximum %d", length, MaxPacketLengthBytes)
}
- content := make([]byte, length, length)
+ content := make([]byte, length)
if length > 0 {
_, err := io.ReadFull(reader, content)
if err != nil {
@@ -377,22 +379,42 @@ func readPacket(reader io.Reader) (*Packet, int, error) {
case TagObjectDescriptor:
case TagExternal:
case TagRealFloat:
+ p.Value, err = ParseReal(content)
case TagEnumerated:
p.Value, _ = ParseInt64(content)
case TagEmbeddedPDV:
case TagUTF8String:
- p.Value = DecodeString(content)
+ val := DecodeString(content)
+ if !utf8.Valid([]byte(val)) {
+ err = errors.New("invalid UTF-8 string")
+ } else {
+ p.Value = val
+ }
case TagRelativeOID:
case TagSequence:
case TagSet:
case TagNumericString:
case TagPrintableString:
- p.Value = DecodeString(content)
+ val := DecodeString(content)
+ if err = isPrintableString(val); err == nil {
+ p.Value = val
+ }
case TagT61String:
case TagVideotexString:
case TagIA5String:
+ val := DecodeString(content)
+ for i, c := range val {
+ if c >= 0x7F {
+ err = fmt.Errorf("invalid character for IA5String at pos %d: %c", i, c)
+ break
+ }
+ }
+ if err == nil {
+ p.Value = val
+ }
case TagUTCTime:
case TagGeneralizedTime:
+ p.Value, err = ParseGeneralizedTime(content)
case TagGraphicString:
case TagVisibleString:
case TagGeneralString:
@@ -404,7 +426,24 @@ func readPacket(reader io.Reader) (*Packet, int, error) {
p.Data.Write(content)
}
- return p, read, nil
+ return p, read, err
+}
+
+func isPrintableString(val string) error {
+ for i, c := range val {
+ switch {
+ case c >= 'a' && c <= 'z':
+ case c >= 'A' && c <= 'Z':
+ case c >= '0' && c <= '9':
+ default:
+ switch c {
+ case '\'', '(', ')', '+', ',', '-', '.', '=', '/', ':', '?', ' ':
+ default:
+ return fmt.Errorf("invalid character in position %d", i)
+ }
+ }
+ }
+ return nil
}
func (p *Packet) Bytes() []byte {
@@ -422,77 +461,99 @@ func (p *Packet) AppendChild(child *Packet) {
p.Children = append(p.Children, child)
}
-func Encode(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
+func Encode(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet {
p := new(Packet)
- p.ClassType = ClassType
- p.TagType = TagType
- p.Tag = Tag
+ p.ClassType = classType
+ p.TagType = tagType
+ p.Tag = tag
p.Data = new(bytes.Buffer)
p.Children = make([]*Packet, 0, 2)
- p.Value = Value
- p.Description = Description
+ p.Value = value
+ p.Description = description
- if Value != nil {
- v := reflect.ValueOf(Value)
+ if value != nil {
+ v := reflect.ValueOf(value)
- if ClassType == ClassUniversal {
- switch Tag {
+ if classType == ClassUniversal {
+ switch tag {
case TagOctetString:
sv, ok := v.Interface().(string)
if ok {
p.Data.Write([]byte(sv))
}
+ case TagEnumerated:
+ bv, ok := v.Interface().([]byte)
+ if ok {
+ p.Data.Write(bv)
+ }
+ case TagEmbeddedPDV:
+ bv, ok := v.Interface().([]byte)
+ if ok {
+ p.Data.Write(bv)
+ }
+ }
+ } else if classType == ClassContext {
+ switch tag {
+ case TagEnumerated:
+ bv, ok := v.Interface().([]byte)
+ if ok {
+ p.Data.Write(bv)
+ }
+ case TagEmbeddedPDV:
+ bv, ok := v.Interface().([]byte)
+ if ok {
+ p.Data.Write(bv)
+ }
}
}
}
-
return p
}
-func NewSequence(Description string) *Packet {
- return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, Description)
+func NewSequence(description string) *Packet {
+ return Encode(ClassUniversal, TypeConstructed, TagSequence, nil, description)
}
-func NewBoolean(ClassType Class, TagType Type, Tag Tag, Value bool, Description string) *Packet {
+func NewBoolean(classType Class, tagType Type, tag Tag, value bool, description string) *Packet {
intValue := int64(0)
- if Value {
+ if value {
intValue = 1
}
- p := Encode(ClassType, TagType, Tag, nil, Description)
+ p := Encode(classType, tagType, tag, nil, description)
- p.Value = Value
+ p.Value = value
p.Data.Write(encodeInteger(intValue))
return p
}
-// NewLDAPBoolean returns a RFC 4511-compliant Boolean packet
-func NewLDAPBoolean(Value bool, Description string) *Packet {
+// NewLDAPBoolean returns a RFC 4511-compliant Boolean packet.
+func NewLDAPBoolean(classType Class, tagType Type, tag Tag, value bool, description string) *Packet {
intValue := int64(0)
- if Value {
+ if value {
intValue = 255
}
- p := Encode(ClassUniversal, TypePrimitive, TagBoolean, nil, Description)
+ p := Encode(classType, tagType, tag, nil, description)
- p.Value = Value
+ p.Value = value
p.Data.Write(encodeInteger(intValue))
return p
}
-func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Description string) *Packet {
- p := Encode(ClassType, TagType, Tag, nil, Description)
+func NewInteger(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet {
+ p := Encode(classType, tagType, tag, nil, description)
- p.Value = Value
- switch v := Value.(type) {
+ p.Value = value
+ switch v := value.(type) {
case int:
p.Data.Write(encodeInteger(int64(v)))
case uint:
@@ -522,11 +583,38 @@ func NewInteger(ClassType Class, TagType Type, Tag Tag, Value interface{}, Descr
return p
}
-func NewString(ClassType Class, TagType Type, Tag Tag, Value, Description string) *Packet {
- p := Encode(ClassType, TagType, Tag, nil, Description)
+func NewString(classType Class, tagType Type, tag Tag, value, description string) *Packet {
+ p := Encode(classType, tagType, tag, nil, description)
+
+ p.Value = value
+ p.Data.Write([]byte(value))
- p.Value = Value
- p.Data.Write([]byte(Value))
+ return p
+}
+func NewGeneralizedTime(classType Class, tagType Type, tag Tag, value time.Time, description string) *Packet {
+ p := Encode(classType, tagType, tag, nil, description)
+ var s string
+ if value.Nanosecond() != 0 {
+ s = value.Format(`20060102150405.000000000Z`)
+ } else {
+ s = value.Format(`20060102150405Z`)
+ }
+ p.Value = s
+ p.Data.Write([]byte(s))
+ return p
+}
+
+func NewReal(classType Class, tagType Type, tag Tag, value interface{}, description string) *Packet {
+ p := Encode(classType, tagType, tag, nil, description)
+
+ switch v := value.(type) {
+ case float64:
+ p.Data.Write(encodeFloat(v))
+ case float32:
+ p.Data.Write(encodeFloat(float64(v)))
+ default:
+ panic(fmt.Sprintf("Invalid type %T, expected float{64|32}", v))
+ }
return p
}
diff --git a/vendor/github.com/go-asn1-ber/asn1-ber/content_int.go b/vendor/github.com/go-asn1-ber/asn1-ber/content_int.go
index 1858b74b..20b500f5 100644
--- a/vendor/github.com/go-asn1-ber/asn1-ber/content_int.go
+++ b/vendor/github.com/go-asn1-ber/asn1-ber/content_int.go
@@ -6,7 +6,7 @@ func encodeUnsignedInteger(i uint64) []byte {
var j int
for ; n > 0; n-- {
- out[j] = (byte(i >> uint((n-1)*8)))
+ out[j] = byte(i >> uint((n-1)*8))
j++
}
diff --git a/vendor/github.com/go-asn1-ber/asn1-ber/generalizedTime.go b/vendor/github.com/go-asn1-ber/asn1-ber/generalizedTime.go
new file mode 100644
index 00000000..51215f06
--- /dev/null
+++ b/vendor/github.com/go-asn1-ber/asn1-ber/generalizedTime.go
@@ -0,0 +1,105 @@
+package ber
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "strconv"
+ "time"
+)
+
+// ErrInvalidTimeFormat is returned when the generalizedTime string was not correct.
+var ErrInvalidTimeFormat = errors.New("invalid time format")
+
+var zeroTime = time.Time{}
+
+// ParseGeneralizedTime parses a string value and if it conforms to
+// GeneralizedTime[^0] format, will return a time.Time for that value.
+//
+// [^0]: https://www.itu.int/rec/T-REC-X.690-201508-I/en Section 11.7
+func ParseGeneralizedTime(v []byte) (time.Time, error) {
+ var format string
+ var fract time.Duration
+
+ str := []byte(DecodeString(v))
+ tzIndex := bytes.IndexAny(str, "Z+-")
+ if tzIndex < 0 {
+ return zeroTime, ErrInvalidTimeFormat
+ }
+
+ dot := bytes.IndexAny(str, ".,")
+ switch dot {
+ case -1:
+ switch tzIndex {
+ case 10:
+ format = `2006010215Z`
+ case 12:
+ format = `200601021504Z`
+ case 14:
+ format = `20060102150405Z`
+ default:
+ return zeroTime, ErrInvalidTimeFormat
+ }
+
+ case 10, 12:
+ if tzIndex < dot {
+ return zeroTime, ErrInvalidTimeFormat
+ }
+ // a "," is also allowed, but would not be parsed by time.Parse():
+ str[dot] = '.'
+
+ // If <minute> is omitted, then <fraction> represents a fraction of an
+ // hour; otherwise, if <second> and <leap-second> are omitted, then
+ // <fraction> represents a fraction of a minute; otherwise, <fraction>
+ // represents a fraction of a second.
+
+ // parse as float from dot to timezone
+ f, err := strconv.ParseFloat(string(str[dot:tzIndex]), 64)
+ if err != nil {
+ return zeroTime, fmt.Errorf("failed to parse float: %s", err)
+ }
+ // ...and strip that part
+ str = append(str[:dot], str[tzIndex:]...)
+ tzIndex = dot
+
+ if dot == 10 {
+ fract = time.Duration(int64(f * float64(time.Hour)))
+ format = `2006010215Z`
+ } else {
+ fract = time.Duration(int64(f * float64(time.Minute)))
+ format = `200601021504Z`
+ }
+
+ case 14:
+ if tzIndex < dot {
+ return zeroTime, ErrInvalidTimeFormat
+ }
+ str[dot] = '.'
+ // no need for fractional seconds, time.Parse() handles that
+ format = `20060102150405Z`
+
+ default:
+ return zeroTime, ErrInvalidTimeFormat
+ }
+
+ l := len(str)
+ switch l - tzIndex {
+ case 1:
+ if str[l-1] != 'Z' {
+ return zeroTime, ErrInvalidTimeFormat
+ }
+ case 3:
+ format += `0700`
+ str = append(str, []byte("00")...)
+ case 5:
+ format += `0700`
+ default:
+ return zeroTime, ErrInvalidTimeFormat
+ }
+
+ t, err := time.Parse(format, string(str))
+ if err != nil {
+ return zeroTime, fmt.Errorf("%s: %s", ErrInvalidTimeFormat, err)
+ }
+ return t.Add(fract), nil
+}
diff --git a/vendor/github.com/go-asn1-ber/asn1-ber/header.go b/vendor/github.com/go-asn1-ber/asn1-ber/header.go
index 71615621..7dfa6b9a 100644
--- a/vendor/github.com/go-asn1-ber/asn1-ber/header.go
+++ b/vendor/github.com/go-asn1-ber/asn1-ber/header.go
@@ -7,19 +7,22 @@ import (
)
func readHeader(reader io.Reader) (identifier Identifier, length int, read int, err error) {
- if i, c, err := readIdentifier(reader); err != nil {
+ var (
+ c, l int
+ i Identifier
+ )
+
+ if i, c, err = readIdentifier(reader); err != nil {
return Identifier{}, 0, read, err
- } else {
- identifier = i
- read += c
}
+ identifier = i
+ read += c
- if l, c, err := readLength(reader); err != nil {
+ if l, c, err = readLength(reader); err != nil {
return Identifier{}, 0, read, err
- } else {
- length = l
- read += c
}
+ length = l
+ read += c
// Validate length type with identifier (x.600, 8.1.3.2.a)
if length == LengthIndefinite && identifier.TagType == TypePrimitive {
diff --git a/vendor/github.com/go-asn1-ber/asn1-ber/length.go b/vendor/github.com/go-asn1-ber/asn1-ber/length.go
index 750e8f44..9cc195d0 100644
--- a/vendor/github.com/go-asn1-ber/asn1-ber/length.go
+++ b/vendor/github.com/go-asn1-ber/asn1-ber/length.go
@@ -71,11 +71,11 @@ func readLength(reader io.Reader) (length int, read int, err error) {
}
func encodeLength(length int) []byte {
- length_bytes := encodeUnsignedInteger(uint64(length))
- if length > 127 || len(length_bytes) > 1 {
- longFormBytes := []byte{(LengthLongFormBitmask | byte(len(length_bytes)))}
- longFormBytes = append(longFormBytes, length_bytes...)
- length_bytes = longFormBytes
+ lengthBytes := encodeUnsignedInteger(uint64(length))
+ if length > 127 || len(lengthBytes) > 1 {
+ longFormBytes := []byte{LengthLongFormBitmask | byte(len(lengthBytes))}
+ longFormBytes = append(longFormBytes, lengthBytes...)
+ lengthBytes = longFormBytes
}
- return length_bytes
+ return lengthBytes
}
diff --git a/vendor/github.com/go-asn1-ber/asn1-ber/real.go b/vendor/github.com/go-asn1-ber/asn1-ber/real.go
new file mode 100644
index 00000000..610a003a
--- /dev/null
+++ b/vendor/github.com/go-asn1-ber/asn1-ber/real.go
@@ -0,0 +1,157 @@
+package ber
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+)
+
+func encodeFloat(v float64) []byte {
+ switch {
+ case math.IsInf(v, 1):
+ return []byte{0x40}
+ case math.IsInf(v, -1):
+ return []byte{0x41}
+ case math.IsNaN(v):
+ return []byte{0x42}
+ case v == 0.0:
+ if math.Signbit(v) {
+ return []byte{0x43}
+ }
+ return []byte{}
+ default:
+ // we take the easy part ;-)
+ value := []byte(strconv.FormatFloat(v, 'G', -1, 64))
+ var ret []byte
+ if bytes.Contains(value, []byte{'E'}) {
+ ret = []byte{0x03}
+ } else {
+ ret = []byte{0x02}
+ }
+ ret = append(ret, value...)
+ return ret
+ }
+}
+
+func ParseReal(v []byte) (val float64, err error) {
+ if len(v) == 0 {
+ return 0.0, nil
+ }
+ switch {
+ case v[0]&0x80 == 0x80:
+ val, err = parseBinaryFloat(v)
+ case v[0]&0xC0 == 0x40:
+ val, err = parseSpecialFloat(v)
+ case v[0]&0xC0 == 0x0:
+ val, err = parseDecimalFloat(v)
+ default:
+ return 0.0, fmt.Errorf("invalid info block")
+ }
+ if err != nil {
+ return 0.0, err
+ }
+
+ if val == 0.0 && !math.Signbit(val) {
+ return 0.0, errors.New("REAL value +0 must be encoded with zero-length value block")
+ }
+ return val, nil
+}
+
+func parseBinaryFloat(v []byte) (float64, error) {
+ var info byte
+ var buf []byte
+
+ info, v = v[0], v[1:]
+
+ var base int
+ switch info & 0x30 {
+ case 0x00:
+ base = 2
+ case 0x10:
+ base = 8
+ case 0x20:
+ base = 16
+ case 0x30:
+ return 0.0, errors.New("bits 6 and 5 of information octet for REAL are equal to 11")
+ }
+
+ scale := uint((info & 0x0c) >> 2)
+
+ var expLen int
+ switch info & 0x03 {
+ case 0x00:
+ expLen = 1
+ case 0x01:
+ expLen = 2
+ case 0x02:
+ expLen = 3
+ case 0x03:
+ expLen = int(v[0])
+ if expLen > 8 {
+ return 0.0, errors.New("too big value of exponent")
+ }
+ v = v[1:]
+ }
+ buf, v = v[:expLen], v[expLen:]
+ exponent, err := ParseInt64(buf)
+ if err != nil {
+ return 0.0, err
+ }
+
+ if len(v) > 8 {
+ return 0.0, errors.New("too big value of mantissa")
+ }
+
+ mant, err := ParseInt64(v)
+ if err != nil {
+ return 0.0, err
+ }
+ mantissa := mant << scale
+
+ if info&0x40 == 0x40 {
+ mantissa = -mantissa
+ }
+
+ return float64(mantissa) * math.Pow(float64(base), float64(exponent)), nil
+}
+
+func parseDecimalFloat(v []byte) (val float64, err error) {
+ switch v[0] & 0x3F {
+ case 0x01: // NR form 1
+ var iVal int64
+ iVal, err = strconv.ParseInt(strings.TrimLeft(string(v[1:]), " "), 10, 64)
+ val = float64(iVal)
+ case 0x02, 0x03: // NR form 2, 3
+ val, err = strconv.ParseFloat(strings.Replace(strings.TrimLeft(string(v[1:]), " "), ",", ".", -1), 64)
+ default:
+ err = errors.New("incorrect NR form")
+ }
+ if err != nil {
+ return 0.0, err
+ }
+
+ if val == 0.0 && math.Signbit(val) {
+ return 0.0, errors.New("REAL value -0 must be encoded as a special value")
+ }
+ return val, nil
+}
+
+func parseSpecialFloat(v []byte) (float64, error) {
+ if len(v) != 1 {
+ return 0.0, errors.New(`encoding of "special value" must not contain exponent and mantissa`)
+ }
+ switch v[0] {
+ case 0x40:
+ return math.Inf(1), nil
+ case 0x41:
+ return math.Inf(-1), nil
+ case 0x42:
+ return math.NaN(), nil
+ case 0x43:
+ return math.Copysign(0, -1), nil
+ }
+ return 0.0, errors.New(`encoding of "special value" not from ASN.1 standard`)
+}
diff --git a/vendor/github.com/go-asn1-ber/asn1-ber/util.go b/vendor/github.com/go-asn1-ber/asn1-ber/util.go
index 3e56b66c..14dc87d7 100644
--- a/vendor/github.com/go-asn1-ber/asn1-ber/util.go
+++ b/vendor/github.com/go-asn1-ber/asn1-ber/util.go
@@ -3,7 +3,7 @@ package ber
import "io"
func readByte(reader io.Reader) (byte, error) {
- bytes := make([]byte, 1, 1)
+ bytes := make([]byte, 1)
_, err := io.ReadFull(reader, bytes)
if err != nil {
if err == io.EOF {