1
0

Update module lib/pq to v1.6.0 (#572)

Update module lib/pq to v1.6.0

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/572
This commit is contained in:
renovate
2020-05-29 17:47:28 +00:00
committed by konrad
parent 5a04f1ecf4
commit 54b18b3c59
161 changed files with 19472 additions and 7 deletions

413
vendor/github.com/jcmturner/rpc/v2/ndr/arrays.go generated vendored Normal file
View File

@ -0,0 +1,413 @@
package ndr
import (
"errors"
"fmt"
"reflect"
"strconv"
)
// intFromTag returns an int that is a value in a struct tag key/value pair
func intFromTag(tag reflect.StructTag, key string) (int, error) {
ndrTag := parseTags(tag)
d := 1
if n, ok := ndrTag.Map[key]; ok {
i, err := strconv.Atoi(n)
if err != nil {
return d, fmt.Errorf("invalid dimensions tag [%s]: %v", n, err)
}
d = i
}
return d, nil
}
// parseDimensions returns the a slice of the size of each dimension and type of the member at the deepest level.
func parseDimensions(v reflect.Value) (l []int, tb reflect.Type) {
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
t := v.Type()
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Array && t.Kind() != reflect.Slice {
return
}
l = append(l, v.Len())
if t.Elem().Kind() == reflect.Array || t.Elem().Kind() == reflect.Slice {
// contains array or slice
var m []int
m, tb = parseDimensions(v.Index(0))
l = append(l, m...)
} else {
tb = t.Elem()
}
return
}
// sliceDimensions returns the count of dimensions a slice has.
func sliceDimensions(t reflect.Type) (d int, tb reflect.Type) {
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() == reflect.Slice {
d++
var n int
n, tb = sliceDimensions(t.Elem())
d += n
} else {
tb = t
}
return
}
// makeSubSlices is a deep recursive creation/initialisation of multi-dimensional slices.
// Takes the reflect.Value of the 1st dimension and a slice of the lengths of the sub dimensions
func makeSubSlices(v reflect.Value, l []int) {
ty := v.Type().Elem()
if ty.Kind() != reflect.Slice {
return
}
for i := 0; i < v.Len(); i++ {
s := reflect.MakeSlice(ty, l[0], l[0])
v.Index(i).Set(s)
// Are there more sub dimensions?
if len(l) > 1 {
makeSubSlices(v.Index(i), l[1:])
}
}
return
}
// multiDimensionalIndexPermutations returns all the permutations of the indexes of a multi-dimensional slice.
// The input is a slice of integers that indicates the max size/length of each dimension
func multiDimensionalIndexPermutations(l []int) (ps [][]int) {
z := make([]int, len(l), len(l)) // The zeros permutation
ps = append(ps, z)
// for each dimension, in reverse
for i := len(l) - 1; i >= 0; i-- {
ws := make([][]int, len(ps))
copy(ws, ps)
//create a permutation for each of the iterations of the current dimension
for j := 1; j <= l[i]-1; j++ {
// For each existing permutation
for _, p := range ws {
np := make([]int, len(p), len(p))
copy(np, p)
np[i] = j
ps = append(ps, np)
}
}
}
return
}
// precedingMax reads off the next conformant max value
func (dec *Decoder) precedingMax() uint32 {
m := dec.conformantMax[0]
dec.conformantMax = dec.conformantMax[1:]
return m
}
// fillFixedArray establishes if the fixed array is uni or multi dimensional and then fills it.
func (dec *Decoder) fillFixedArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
l, t := parseDimensions(v)
if t.Kind() == reflect.String {
tag = reflect.StructTag(subStringArrayTag)
}
if len(l) < 1 {
return errors.New("could not establish dimensions of fixed array")
}
if len(l) == 1 {
err := dec.fillUniDimensionalFixedArray(v, tag, def)
if err != nil {
return fmt.Errorf("could not fill uni-dimensional fixed array: %v", err)
}
return nil
}
// Fixed array is multidimensional
ps := multiDimensionalIndexPermutations(l[:len(l)-1])
for _, p := range ps {
// Get current multi-dimensional index to fill
a := v
for _, i := range p {
a = a.Index(i)
}
// fill with the last dimension array
err := dec.fillUniDimensionalFixedArray(a, tag, def)
if err != nil {
return fmt.Errorf("could not fill dimension %v of multi-dimensional fixed array: %v", p, err)
}
}
return nil
}
// readUniDimensionalFixedArray reads an array (not slice) from the byte stream.
func (dec *Decoder) fillUniDimensionalFixedArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
for i := 0; i < v.Len(); i++ {
err := dec.fill(v.Index(i), tag, def)
if err != nil {
return fmt.Errorf("could not fill index %d of fixed array: %v", i, err)
}
}
return nil
}
// fillConformantArray establishes if the conformant array is uni or multi dimensional and then fills the slice.
func (dec *Decoder) fillConformantArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
d, _ := sliceDimensions(v.Type())
if d > 1 {
err := dec.fillMultiDimensionalConformantArray(v, d, tag, def)
if err != nil {
return err
}
} else {
err := dec.fillUniDimensionalConformantArray(v, tag, def)
if err != nil {
return err
}
}
return nil
}
// fillUniDimensionalConformantArray fills the uni-dimensional slice value.
func (dec *Decoder) fillUniDimensionalConformantArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
m := dec.precedingMax()
n := int(m)
a := reflect.MakeSlice(v.Type(), n, n)
for i := 0; i < n; i++ {
err := dec.fill(a.Index(i), tag, def)
if err != nil {
return fmt.Errorf("could not fill index %d of uni-dimensional conformant array: %v", i, err)
}
}
v.Set(a)
return nil
}
// fillMultiDimensionalConformantArray fills the multi-dimensional slice value provided from conformant array data.
// The number of dimensions must be specified. This must be less than or equal to the dimensions in the slice for this
// method not to panic.
func (dec *Decoder) fillMultiDimensionalConformantArray(v reflect.Value, d int, tag reflect.StructTag, def *[]deferedPtr) error {
// Read the max size of each dimensions from the ndr stream
l := make([]int, d, d)
for i := range l {
l[i] = int(dec.precedingMax())
}
// Initialise size of slices
// Initialise the size of the 1st dimension
ty := v.Type()
v.Set(reflect.MakeSlice(ty, l[0], l[0]))
// Initialise the size of the other dimensions recursively
makeSubSlices(v, l[1:])
// Get all permutations of the indexes and go through each and fill
ps := multiDimensionalIndexPermutations(l)
for _, p := range ps {
// Get current multi-dimensional index to fill
a := v
for _, i := range p {
a = a.Index(i)
}
err := dec.fill(a, tag, def)
if err != nil {
return fmt.Errorf("could not fill index %v of slice: %v", p, err)
}
}
return nil
}
// fillVaryingArray establishes if the varying array is uni or multi dimensional and then fills the slice.
func (dec *Decoder) fillVaryingArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
d, t := sliceDimensions(v.Type())
if d > 1 {
err := dec.fillMultiDimensionalVaryingArray(v, t, d, tag, def)
if err != nil {
return err
}
} else {
err := dec.fillUniDimensionalVaryingArray(v, tag, def)
if err != nil {
return err
}
}
return nil
}
// fillUniDimensionalVaryingArray fills the uni-dimensional slice value.
func (dec *Decoder) fillUniDimensionalVaryingArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
o, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not read offset of uni-dimensional varying array: %v", err)
}
s, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not establish actual count of uni-dimensional varying array: %v", err)
}
t := v.Type()
// Total size of the array is the offset in the index being passed plus the actual count of elements being passed.
n := int(s + o)
a := reflect.MakeSlice(t, n, n)
// Populate the array starting at the offset specified
for i := int(o); i < n; i++ {
err := dec.fill(a.Index(i), tag, def)
if err != nil {
return fmt.Errorf("could not fill index %d of uni-dimensional varying array: %v", i, err)
}
}
v.Set(a)
return nil
}
// fillMultiDimensionalVaryingArray fills the multi-dimensional slice value provided from varying array data.
// The number of dimensions must be specified. This must be less than or equal to the dimensions in the slice for this
// method not to panic.
func (dec *Decoder) fillMultiDimensionalVaryingArray(v reflect.Value, t reflect.Type, d int, tag reflect.StructTag, def *[]deferedPtr) error {
// Read the offset and actual count of each dimensions from the ndr stream
o := make([]int, d, d)
l := make([]int, d, d)
for i := range l {
off, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not read offset of dimension %d: %v", i+1, err)
}
o[i] = int(off)
s, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not read size of dimension %d: %v", i+1, err)
}
l[i] = int(s) + int(off)
}
// Initialise size of slices
// Initialise the size of the 1st dimension
ty := v.Type()
v.Set(reflect.MakeSlice(ty, l[0], l[0]))
// Initialise the size of the other dimensions recursively
makeSubSlices(v, l[1:])
// Get all permutations of the indexes and go through each and fill
ps := multiDimensionalIndexPermutations(l)
for _, p := range ps {
// Get current multi-dimensional index to fill
a := v
var os bool // should this permutation be skipped due to the offset of any of the dimensions?
for i, j := range p {
if j < o[i] {
os = true
break
}
a = a.Index(j)
}
if os {
// This permutation should be skipped as it is less than the offset for one of the dimensions.
continue
}
err := dec.fill(a, tag, def)
if err != nil {
return fmt.Errorf("could not fill index %v of slice: %v", p, err)
}
}
return nil
}
// fillConformantVaryingArray establishes if the varying array is uni or multi dimensional and then fills the slice.
func (dec *Decoder) fillConformantVaryingArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
d, t := sliceDimensions(v.Type())
if d > 1 {
err := dec.fillMultiDimensionalConformantVaryingArray(v, t, d, tag, def)
if err != nil {
return err
}
} else {
err := dec.fillUniDimensionalConformantVaryingArray(v, tag, def)
if err != nil {
return err
}
}
return nil
}
// fillUniDimensionalConformantVaryingArray fills the uni-dimensional slice value.
func (dec *Decoder) fillUniDimensionalConformantVaryingArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
m := dec.precedingMax()
o, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not read offset of uni-dimensional conformant varying array: %v", err)
}
s, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not establish actual count of uni-dimensional conformant varying array: %v", err)
}
if m < o+s {
return errors.New("max count is less than the offset plus actual count")
}
t := v.Type()
n := int(s)
a := reflect.MakeSlice(t, n, n)
for i := int(o); i < n; i++ {
err := dec.fill(a.Index(i), tag, def)
if err != nil {
return fmt.Errorf("could not fill index %d of uni-dimensional conformant varying array: %v", i, err)
}
}
v.Set(a)
return nil
}
// fillMultiDimensionalConformantVaryingArray fills the multi-dimensional slice value provided from conformant varying array data.
// The number of dimensions must be specified. This must be less than or equal to the dimensions in the slice for this
// method not to panic.
func (dec *Decoder) fillMultiDimensionalConformantVaryingArray(v reflect.Value, t reflect.Type, d int, tag reflect.StructTag, def *[]deferedPtr) error {
// Read the offset and actual count of each dimensions from the ndr stream
m := make([]int, d, d)
for i := range m {
m[i] = int(dec.precedingMax())
}
o := make([]int, d, d)
l := make([]int, d, d)
for i := range l {
off, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not read offset of dimension %d: %v", i+1, err)
}
o[i] = int(off)
s, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not read actual count of dimension %d: %v", i+1, err)
}
if m[i] < int(s)+int(off) {
m[i] = int(s) + int(off)
}
l[i] = int(s)
}
// Initialise size of slices
// Initialise the size of the 1st dimension
ty := v.Type()
v.Set(reflect.MakeSlice(ty, m[0], m[0]))
// Initialise the size of the other dimensions recursively
makeSubSlices(v, m[1:])
// Get all permutations of the indexes and go through each and fill
ps := multiDimensionalIndexPermutations(m)
for _, p := range ps {
// Get current multi-dimensional index to fill
a := v
var os bool // should this permutation be skipped due to the offset of any of the dimensions or max is higher than the actual count being passed
for i, j := range p {
if j < o[i] || j >= l[i] {
os = true
break
}
a = a.Index(j)
}
if os {
// This permutation should be skipped as it is less than the offset for one of the dimensions.
continue
}
err := dec.fill(a, tag, def)
if err != nil {
return fmt.Errorf("could not fill index %v of slice: %v", p, err)
}
}
return nil
}

393
vendor/github.com/jcmturner/rpc/v2/ndr/decoder.go generated vendored Normal file
View File

@ -0,0 +1,393 @@
// Package ndr provides the ability to unmarshal NDR encoded byte steams into Go data structures
package ndr
import (
"bufio"
"fmt"
"io"
"reflect"
"strings"
)
// Struct tag values
const (
TagConformant = "conformant"
TagVarying = "varying"
TagPointer = "pointer"
TagPipe = "pipe"
)
// Decoder unmarshals NDR byte stream data into a Go struct representation
type Decoder struct {
r *bufio.Reader // source of the data
size int // initial size of bytes in buffer
ch CommonHeader // NDR common header
ph PrivateHeader // NDR private header
conformantMax []uint32 // conformant max values that were moved to the beginning of the structure
s interface{} // pointer to the structure being populated
current []string // keeps track of the current field being populated
}
type deferedPtr struct {
v reflect.Value
tag reflect.StructTag
}
// NewDecoder creates a new instance of a NDR Decoder.
func NewDecoder(r io.Reader) *Decoder {
dec := new(Decoder)
dec.r = bufio.NewReader(r)
dec.r.Peek(int(commonHeaderBytes)) // For some reason an operation is needed on the buffer to initialise it so Buffered() != 0
dec.size = dec.r.Buffered()
return dec
}
// Decode unmarshals the NDR encoded bytes into the pointer of a struct provided.
func (dec *Decoder) Decode(s interface{}) error {
dec.s = s
err := dec.readCommonHeader()
if err != nil {
return err
}
err = dec.readPrivateHeader()
if err != nil {
return err
}
_, err = dec.r.Discard(4) //The next 4 bytes are an RPC unique pointer referent. We just skip these.
if err != nil {
return Errorf("unable to process byte stream: %v", err)
}
return dec.process(s, reflect.StructTag(""))
}
func (dec *Decoder) process(s interface{}, tag reflect.StructTag) error {
// Scan for conformant fields as their max counts are moved to the beginning
// http://pubs.opengroup.org/onlinepubs/9629399/chap14.htm#tagfcjh_37
err := dec.scanConformantArrays(s, tag)
if err != nil {
return err
}
// Recursively fill the struct fields
var localDef []deferedPtr
err = dec.fill(s, tag, &localDef)
if err != nil {
return Errorf("could not decode: %v", err)
}
// Read any deferred referents associated with pointers
for _, p := range localDef {
err = dec.process(p.v, p.tag)
if err != nil {
return fmt.Errorf("could not decode deferred referent: %v", err)
}
}
return nil
}
// scanConformantArrays scans the structure for embedded conformant fields and captures the maximum element counts for
// dimensions of the array that are moved to the beginning of the structure.
func (dec *Decoder) scanConformantArrays(s interface{}, tag reflect.StructTag) error {
err := dec.conformantScan(s, tag)
if err != nil {
return fmt.Errorf("failed to scan for embedded conformant arrays: %v", err)
}
for i := range dec.conformantMax {
dec.conformantMax[i], err = dec.readUint32()
if err != nil {
return fmt.Errorf("could not read preceding conformant max count index %d: %v", i, err)
}
}
return nil
}
// conformantScan inspects the structure's fields for whether they are conformant.
func (dec *Decoder) conformantScan(s interface{}, tag reflect.StructTag) error {
ndrTag := parseTags(tag)
if ndrTag.HasValue(TagPointer) {
return nil
}
v := getReflectValue(s)
switch v.Kind() {
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
err := dec.conformantScan(v.Field(i), v.Type().Field(i).Tag)
if err != nil {
return err
}
}
case reflect.String:
if !ndrTag.HasValue(TagConformant) {
break
}
dec.conformantMax = append(dec.conformantMax, uint32(0))
case reflect.Slice:
if !ndrTag.HasValue(TagConformant) {
break
}
d, t := sliceDimensions(v.Type())
for i := 0; i < d; i++ {
dec.conformantMax = append(dec.conformantMax, uint32(0))
}
// For string arrays there is a common max for the strings within the array.
if t.Kind() == reflect.String {
dec.conformantMax = append(dec.conformantMax, uint32(0))
}
}
return nil
}
func (dec *Decoder) isPointer(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) (bool, error) {
// Pointer so defer filling the referent
ndrTag := parseTags(tag)
if ndrTag.HasValue(TagPointer) {
p, err := dec.readUint32()
if err != nil {
return true, fmt.Errorf("could not read pointer: %v", err)
}
ndrTag.delete(TagPointer)
if p != 0 {
// if pointer is not zero add to the deferred items at end of stream
*def = append(*def, deferedPtr{v, ndrTag.StructTag()})
}
return true, nil
}
return false, nil
}
func getReflectValue(s interface{}) (v reflect.Value) {
if r, ok := s.(reflect.Value); ok {
v = r
} else {
if reflect.ValueOf(s).Kind() == reflect.Ptr {
v = reflect.ValueOf(s).Elem()
}
}
return
}
// fill populates fields with values from the NDR byte stream.
func (dec *Decoder) fill(s interface{}, tag reflect.StructTag, localDef *[]deferedPtr) error {
v := getReflectValue(s)
//// Pointer so defer filling the referent
ptr, err := dec.isPointer(v, tag, localDef)
if err != nil {
return fmt.Errorf("could not process struct field(%s): %v", strings.Join(dec.current, "/"), err)
}
if ptr {
return nil
}
// Populate the value from the byte stream
switch v.Kind() {
case reflect.Struct:
dec.current = append(dec.current, v.Type().Name()) //Track the current field being filled
// in case struct is a union, track this and the selected union field for efficiency
var unionTag reflect.Value
var unionField string // field to fill if struct is a union
// Go through each field in the struct and recursively fill
for i := 0; i < v.NumField(); i++ {
fieldName := v.Type().Field(i).Name
dec.current = append(dec.current, fieldName) //Track the current field being filled
//fmt.Fprintf(os.Stderr, "DEBUG Decoding: %s\n", strings.Join(dec.current, "/"))
structTag := v.Type().Field(i).Tag
ndrTag := parseTags(structTag)
// Union handling
if !unionTag.IsValid() {
// Is this field a union tag?
unionTag = dec.isUnion(v.Field(i), structTag)
} else {
// What is the selected field value of the union if we don't already know
if unionField == "" {
unionField, err = unionSelectedField(v, unionTag)
if err != nil {
return fmt.Errorf("could not determine selected union value field for %s with discriminat"+
" tag %s: %v", v.Type().Name(), unionTag, err)
}
}
if ndrTag.HasValue(TagUnionField) && fieldName != unionField {
// is a union and this field has not been selected so will skip it.
dec.current = dec.current[:len(dec.current)-1] //This field has been skipped so remove it from the current field tracker
continue
}
}
// Check if field is a pointer
if v.Field(i).Type().Implements(reflect.TypeOf(new(RawBytes)).Elem()) &&
v.Field(i).Type().Kind() == reflect.Slice && v.Field(i).Type().Elem().Kind() == reflect.Uint8 {
//field is for rawbytes
structTag, err = addSizeToTag(v, v.Field(i), structTag)
if err != nil {
return fmt.Errorf("could not get rawbytes field(%s) size: %v", strings.Join(dec.current, "/"), err)
}
ptr, err := dec.isPointer(v.Field(i), structTag, localDef)
if err != nil {
return fmt.Errorf("could not process struct field(%s): %v", strings.Join(dec.current, "/"), err)
}
if !ptr {
err := dec.readRawBytes(v.Field(i), structTag)
if err != nil {
return fmt.Errorf("could not fill raw bytes struct field(%s): %v", strings.Join(dec.current, "/"), err)
}
}
} else {
err := dec.fill(v.Field(i), structTag, localDef)
if err != nil {
return fmt.Errorf("could not fill struct field(%s): %v", strings.Join(dec.current, "/"), err)
}
}
dec.current = dec.current[:len(dec.current)-1] //This field has been filled so remove it from the current field tracker
}
dec.current = dec.current[:len(dec.current)-1] //This field has been filled so remove it from the current field tracker
case reflect.Bool:
i, err := dec.readBool()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Uint8:
i, err := dec.readUint8()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Uint16:
i, err := dec.readUint16()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Uint32:
i, err := dec.readUint32()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Uint64:
i, err := dec.readUint64()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Int8:
i, err := dec.readInt8()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Int16:
i, err := dec.readInt16()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Int32:
i, err := dec.readInt32()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Int64:
i, err := dec.readInt64()
if err != nil {
return fmt.Errorf("could not fill %s: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.String:
ndrTag := parseTags(tag)
conformant := ndrTag.HasValue(TagConformant)
// strings are always varying so this is assumed without an explicit tag
var s string
var err error
if conformant {
s, err = dec.readConformantVaryingString(localDef)
if err != nil {
return fmt.Errorf("could not fill with conformant varying string: %v", err)
}
} else {
s, err = dec.readVaryingString(localDef)
if err != nil {
return fmt.Errorf("could not fill with varying string: %v", err)
}
}
v.Set(reflect.ValueOf(s))
case reflect.Float32:
i, err := dec.readFloat32()
if err != nil {
return fmt.Errorf("could not fill %v: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Float64:
i, err := dec.readFloat64()
if err != nil {
return fmt.Errorf("could not fill %v: %v", v.Type().Name(), err)
}
v.Set(reflect.ValueOf(i))
case reflect.Array:
err := dec.fillFixedArray(v, tag, localDef)
if err != nil {
return err
}
case reflect.Slice:
if v.Type().Implements(reflect.TypeOf(new(RawBytes)).Elem()) && v.Type().Elem().Kind() == reflect.Uint8 {
//field is for rawbytes
err := dec.readRawBytes(v, tag)
if err != nil {
return fmt.Errorf("could not fill raw bytes struct field(%s): %v", strings.Join(dec.current, "/"), err)
}
break
}
ndrTag := parseTags(tag)
conformant := ndrTag.HasValue(TagConformant)
varying := ndrTag.HasValue(TagVarying)
if ndrTag.HasValue(TagPipe) {
err := dec.fillPipe(v, tag)
if err != nil {
return err
}
break
}
_, t := sliceDimensions(v.Type())
if t.Kind() == reflect.String && !ndrTag.HasValue(subStringArrayValue) {
// String array
err := dec.readStringsArray(v, tag, localDef)
if err != nil {
return err
}
break
}
// varying is assumed as fixed arrays use the Go array type rather than slice
if conformant && varying {
err := dec.fillConformantVaryingArray(v, tag, localDef)
if err != nil {
return err
}
} else if !conformant && varying {
err := dec.fillVaryingArray(v, tag, localDef)
if err != nil {
return err
}
} else {
//default to conformant and not varying
err := dec.fillConformantArray(v, tag, localDef)
if err != nil {
return err
}
}
default:
return fmt.Errorf("unsupported type")
}
return nil
}
// readBytes returns a number of bytes from the NDR byte stream.
func (dec *Decoder) readBytes(n int) ([]byte, error) {
//TODO make this take an int64 as input to allow for larger values on all systems?
b := make([]byte, n, n)
m, err := dec.r.Read(b)
if err != nil || m != n {
return b, fmt.Errorf("error reading bytes from stream: %v", err)
}
return b, nil
}

18
vendor/github.com/jcmturner/rpc/v2/ndr/error.go generated vendored Normal file
View File

@ -0,0 +1,18 @@
package ndr
import "fmt"
// Malformed implements the error interface for malformed NDR encoding errors.
type Malformed struct {
EText string
}
// Error implements the error interface on the Malformed struct.
func (e Malformed) Error() string {
return fmt.Sprintf("malformed NDR stream: %s", e.EText)
}
// Errorf formats an error message into a malformed NDR error.
func Errorf(format string, a ...interface{}) Malformed {
return Malformed{EText: fmt.Sprintf(format, a...)}
}

116
vendor/github.com/jcmturner/rpc/v2/ndr/header.go generated vendored Normal file
View File

@ -0,0 +1,116 @@
package ndr
import (
"encoding/binary"
"fmt"
)
/*
Serialization Version 1
https://msdn.microsoft.com/en-us/library/cc243563.aspx
Common Header - https://msdn.microsoft.com/en-us/library/cc243890.aspx
8 bytes in total:
- First byte - Version: Must equal 1
- Second byte - 1st 4 bits: Endianess (0=Big; 1=Little); 2nd 4 bits: Character Encoding (0=ASCII; 1=EBCDIC)
- 3rd - Floating point representation (This does not seem to be the case in examples for Microsoft test sources)
- 4th - Common Header Length: Must equal 8
- 5th - 8th - Filler: MUST be set to 0xcccccccc on marshaling, and SHOULD be ignored during unmarshaling.
Private Header - https://msdn.microsoft.com/en-us/library/cc243919.aspx
8 bytes in total:
- First 4 bytes - Indicates the length of a serialized top-level type in the octet stream. It MUST include the padding length and exclude the header itself.
- Second 4 bytes - Filler: MUST be set to 0 (zero) during marshaling, and SHOULD be ignored during unmarshaling.
*/
const (
protocolVersion uint8 = 1
commonHeaderBytes uint16 = 8
bigEndian = 0
littleEndian = 1
ascii uint8 = 0
ebcdic uint8 = 1
ieee uint8 = 0
vax uint8 = 1
cray uint8 = 2
ibm uint8 = 3
)
// CommonHeader implements the NDR common header: https://msdn.microsoft.com/en-us/library/cc243889.aspx
type CommonHeader struct {
Version uint8
Endianness binary.ByteOrder
CharacterEncoding uint8
FloatRepresentation uint8
HeaderLength uint16
Filler []byte
}
// PrivateHeader implements the NDR private header: https://msdn.microsoft.com/en-us/library/cc243919.aspx
type PrivateHeader struct {
ObjectBufferLength uint32
Filler []byte
}
func (dec *Decoder) readCommonHeader() error {
// Version
vb, err := dec.r.ReadByte()
if err != nil {
return Malformed{EText: "could not read first byte of common header for version"}
}
dec.ch.Version = uint8(vb)
if dec.ch.Version != protocolVersion {
return Malformed{EText: fmt.Sprintf("byte stream does not indicate a RPC Type serialization of version %v", protocolVersion)}
}
// Read Endianness & Character Encoding
eb, err := dec.r.ReadByte()
if err != nil {
return Malformed{EText: "could not read second byte of common header for endianness"}
}
endian := int(eb >> 4 & 0xF)
if endian != 0 && endian != 1 {
return Malformed{EText: "common header does not indicate a valid endianness"}
}
dec.ch.CharacterEncoding = uint8(vb & 0xF)
if dec.ch.CharacterEncoding != 0 && dec.ch.CharacterEncoding != 1 {
return Malformed{EText: "common header does not indicate a valid character encoding"}
}
switch endian {
case littleEndian:
dec.ch.Endianness = binary.LittleEndian
case bigEndian:
dec.ch.Endianness = binary.BigEndian
}
// Common header length
lb, err := dec.readBytes(2)
if err != nil {
return Malformed{EText: fmt.Sprintf("could not read common header length: %v", err)}
}
dec.ch.HeaderLength = dec.ch.Endianness.Uint16(lb)
if dec.ch.HeaderLength != commonHeaderBytes {
return Malformed{EText: "common header does not indicate a valid length"}
}
// Filler bytes
dec.ch.Filler, err = dec.readBytes(4)
if err != nil {
return Malformed{EText: fmt.Sprintf("could not read common header filler: %v", err)}
}
return nil
}
func (dec *Decoder) readPrivateHeader() error {
// The next 8 bytes after the common header comprise the RPC type marshalling private header for constructed types.
err := binary.Read(dec.r, dec.ch.Endianness, &dec.ph.ObjectBufferLength)
if err != nil {
return Malformed{EText: "could not read private header object buffer length"}
}
if dec.ph.ObjectBufferLength%8 != 0 {
return Malformed{EText: "object buffer length not a multiple of 8"}
}
// Filler bytes
dec.ph.Filler, err = dec.readBytes(4)
if err != nil {
return Malformed{EText: fmt.Sprintf("could not read private header filler: %v", err)}
}
return nil
}

31
vendor/github.com/jcmturner/rpc/v2/ndr/pipe.go generated vendored Normal file
View File

@ -0,0 +1,31 @@
package ndr
import (
"fmt"
"reflect"
)
func (dec *Decoder) fillPipe(v reflect.Value, tag reflect.StructTag) error {
s, err := dec.readUint32() // read element count of first chunk
if err != nil {
return err
}
a := reflect.MakeSlice(v.Type(), 0, 0)
c := reflect.MakeSlice(v.Type(), int(s), int(s))
for s != 0 {
for i := 0; i < int(s); i++ {
err := dec.fill(c.Index(i), tag, &[]deferedPtr{})
if err != nil {
return fmt.Errorf("could not fill element %d of pipe: %v", i, err)
}
}
s, err = dec.readUint32() // read element count of first chunk
if err != nil {
return err
}
a = reflect.AppendSlice(a, c)
c = reflect.MakeSlice(v.Type(), int(s), int(s))
}
v.Set(a)
return nil
}

211
vendor/github.com/jcmturner/rpc/v2/ndr/primitives.go generated vendored Normal file
View File

@ -0,0 +1,211 @@
package ndr
import (
"bytes"
"encoding/binary"
"math"
)
// Byte sizes of primitive types
const (
SizeBool = 1
SizeChar = 1
SizeUint8 = 1
SizeUint16 = 2
SizeUint32 = 4
SizeUint64 = 8
SizeEnum = 2
SizeSingle = 4
SizeDouble = 8
SizePtr = 4
)
// Bool is an NDR Boolean which is a logical quantity that assumes one of two values: TRUE or FALSE.
// NDR represents a Boolean as one octet.
// It represents a value of FALSE as a zero octet, an octet in which every bit is reset.
// It represents a value of TRUE as a non-zero octet, an octet in which one or more bits are set.
// Char is an NDR character.
// NDR represents a character as one octet.
// Characters have two representation formats: ASCII and EBCDIC.
// USmall is an unsigned 8 bit integer
// UShort is an unsigned 16 bit integer
// ULong is an unsigned 32 bit integer
// UHyper is an unsigned 64 bit integer
// Small is an signed 8 bit integer
// Short is an signed 16 bit integer
// Long is an signed 32 bit integer
// Hyper is an signed 64 bit integer
// Enum is the NDR representation of enumerated types as signed short integers (2 octets)
// Single is an NDR defined single-precision floating-point data type
// Double is an NDR defined double-precision floating-point data type
// readBool reads a byte representing a boolean.
// NDR represents a Boolean as one octet.
// It represents a value of FALSE as a zero octet, an octet in which every bit is reset.
// It represents a value of TRUE as a non-zero octet, an octet in which one or more bits are set.
func (dec *Decoder) readBool() (bool, error) {
i, err := dec.readUint8()
if err != nil {
return false, err
}
if i != 0 {
return true, nil
}
return false, nil
}
// readChar reads bytes representing a 8bit ASCII integer cast to a rune.
func (dec *Decoder) readChar() (rune, error) {
var r rune
a, err := dec.readUint8()
if err != nil {
return r, err
}
return rune(a), nil
}
// readUint8 reads bytes representing a 8bit unsigned integer.
func (dec *Decoder) readUint8() (uint8, error) {
b, err := dec.r.ReadByte()
if err != nil {
return uint8(0), err
}
return uint8(b), nil
}
// readUint16 reads bytes representing a 16bit unsigned integer.
func (dec *Decoder) readUint16() (uint16, error) {
dec.ensureAlignment(SizeUint16)
b, err := dec.readBytes(SizeUint16)
if err != nil {
return uint16(0), err
}
return dec.ch.Endianness.Uint16(b), nil
}
// readUint32 reads bytes representing a 32bit unsigned integer.
func (dec *Decoder) readUint32() (uint32, error) {
dec.ensureAlignment(SizeUint32)
b, err := dec.readBytes(SizeUint32)
if err != nil {
return uint32(0), err
}
return dec.ch.Endianness.Uint32(b), nil
}
// readUint32 reads bytes representing a 32bit unsigned integer.
func (dec *Decoder) readUint64() (uint64, error) {
dec.ensureAlignment(SizeUint64)
b, err := dec.readBytes(SizeUint64)
if err != nil {
return uint64(0), err
}
return dec.ch.Endianness.Uint64(b), nil
}
func (dec *Decoder) readInt8() (int8, error) {
dec.ensureAlignment(SizeUint8)
b, err := dec.readBytes(SizeUint8)
if err != nil {
return 0, err
}
var i int8
buf := bytes.NewReader(b)
err = binary.Read(buf, dec.ch.Endianness, &i)
if err != nil {
return 0, err
}
return i, nil
}
func (dec *Decoder) readInt16() (int16, error) {
dec.ensureAlignment(SizeUint16)
b, err := dec.readBytes(SizeUint16)
if err != nil {
return 0, err
}
var i int16
buf := bytes.NewReader(b)
err = binary.Read(buf, dec.ch.Endianness, &i)
if err != nil {
return 0, err
}
return i, nil
}
func (dec *Decoder) readInt32() (int32, error) {
dec.ensureAlignment(SizeUint32)
b, err := dec.readBytes(SizeUint32)
if err != nil {
return 0, err
}
var i int32
buf := bytes.NewReader(b)
err = binary.Read(buf, dec.ch.Endianness, &i)
if err != nil {
return 0, err
}
return i, nil
}
func (dec *Decoder) readInt64() (int64, error) {
dec.ensureAlignment(SizeUint64)
b, err := dec.readBytes(SizeUint64)
if err != nil {
return 0, err
}
var i int64
buf := bytes.NewReader(b)
err = binary.Read(buf, dec.ch.Endianness, &i)
if err != nil {
return 0, err
}
return i, nil
}
// https://en.wikipedia.org/wiki/IEEE_754-1985
func (dec *Decoder) readFloat32() (f float32, err error) {
dec.ensureAlignment(SizeSingle)
b, err := dec.readBytes(SizeSingle)
if err != nil {
return
}
bits := dec.ch.Endianness.Uint32(b)
f = math.Float32frombits(bits)
return
}
func (dec *Decoder) readFloat64() (f float64, err error) {
dec.ensureAlignment(SizeDouble)
b, err := dec.readBytes(SizeDouble)
if err != nil {
return
}
bits := dec.ch.Endianness.Uint64(b)
f = math.Float64frombits(bits)
return
}
// NDR enforces NDR alignment of primitive data; that is, any primitive of size n octets is aligned at a octet stream
// index that is a multiple of n. (In this version of NDR, n is one of {1, 2, 4, 8}.) An octet stream index indicates
// the number of an octet in an octet stream when octets are numbered, beginning with 0, from the first octet in the
// stream. Where necessary, an alignment gap, consisting of octets of unspecified value, precedes the representation
// of a primitive. The gap is of the smallest size sufficient to align the primitive.
func (dec *Decoder) ensureAlignment(n int) {
p := dec.size - dec.r.Buffered()
if s := p % n; s != 0 {
dec.r.Discard(n - s)
}
}

61
vendor/github.com/jcmturner/rpc/v2/ndr/rawbytes.go generated vendored Normal file
View File

@ -0,0 +1,61 @@
package ndr
import (
"errors"
"fmt"
"reflect"
"strconv"
)
// type MyBytes []byte
// implement RawBytes interface
const (
sizeMethod = "Size"
)
// RawBytes interface should be implemented if reading just a number of bytes from the NDR stream
type RawBytes interface {
Size(interface{}) int
}
func rawBytesSize(parent reflect.Value, v reflect.Value) (int, error) {
sf := v.MethodByName(sizeMethod)
if !sf.IsValid() {
return 0, fmt.Errorf("could not find a method called %s on the implementation of RawBytes", sizeMethod)
}
in := []reflect.Value{parent}
f := sf.Call(in)
if f[0].Kind() != reflect.Int {
return 0, errors.New("the RawBytes size function did not return an integer")
}
return int(f[0].Int()), nil
}
func addSizeToTag(parent reflect.Value, v reflect.Value, tag reflect.StructTag) (reflect.StructTag, error) {
size, err := rawBytesSize(parent, v)
if err != nil {
return tag, err
}
ndrTag := parseTags(tag)
ndrTag.Map["size"] = strconv.Itoa(size)
return ndrTag.StructTag(), nil
}
func (dec *Decoder) readRawBytes(v reflect.Value, tag reflect.StructTag) error {
ndrTag := parseTags(tag)
sizeStr, ok := ndrTag.Map["size"]
if !ok {
return errors.New("size tag not available")
}
size, err := strconv.Atoi(sizeStr)
if err != nil {
return fmt.Errorf("size not valid: %v", err)
}
b, err := dec.readBytes(size)
if err != nil {
return err
}
v.Set(reflect.ValueOf(b).Convert(v.Type()))
return nil
}

70
vendor/github.com/jcmturner/rpc/v2/ndr/strings.go generated vendored Normal file
View File

@ -0,0 +1,70 @@
package ndr
import (
"fmt"
"reflect"
)
const (
subStringArrayTag = `ndr:"varying,X-subStringArray"`
subStringArrayValue = "X-subStringArray"
)
func uint16SliceToString(a []uint16) string {
s := make([]rune, len(a), len(a))
for i := range s {
s[i] = rune(a[i])
}
if len(s) > 0 {
// Remove any null terminator
if s[len(s)-1] == rune(0) {
s = s[:len(s)-1]
}
}
return string(s)
}
func (dec *Decoder) readVaryingString(def *[]deferedPtr) (string, error) {
a := new([]uint16)
v := reflect.ValueOf(a)
var t reflect.StructTag
err := dec.fillUniDimensionalVaryingArray(v.Elem(), t, def)
if err != nil {
return "", err
}
s := uint16SliceToString(*a)
return s, nil
}
func (dec *Decoder) readConformantVaryingString(def *[]deferedPtr) (string, error) {
a := new([]uint16)
v := reflect.ValueOf(a)
var t reflect.StructTag
err := dec.fillUniDimensionalConformantVaryingArray(v.Elem(), t, def)
if err != nil {
return "", err
}
s := uint16SliceToString(*a)
return s, nil
}
func (dec *Decoder) readStringsArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
d, _ := sliceDimensions(v.Type())
ndrTag := parseTags(tag)
var m []int
//var ms int
if ndrTag.HasValue(TagConformant) {
for i := 0; i < d; i++ {
m = append(m, int(dec.precedingMax()))
}
//common max size
_ = dec.precedingMax()
//ms = int(n)
}
tag = reflect.StructTag(subStringArrayTag)
err := dec.fillVaryingArray(v, tag, def)
if err != nil {
return fmt.Errorf("could not read string array: %v", err)
}
return nil
}

69
vendor/github.com/jcmturner/rpc/v2/ndr/tags.go generated vendored Normal file
View File

@ -0,0 +1,69 @@
package ndr
import (
"fmt"
"reflect"
"strings"
)
const ndrNameSpace = "ndr"
type tags struct {
Values []string
Map map[string]string
}
// parse the struct field tags and extract the ndr related ones.
// format of tag ndr:"value,key:value1,value2"
func parseTags(st reflect.StructTag) tags {
s := st.Get(ndrNameSpace)
t := tags{
Values: []string{},
Map: make(map[string]string),
}
if s != "" {
ndrTags := strings.Trim(s, `"`)
for _, tag := range strings.Split(ndrTags, ",") {
if strings.Contains(tag, ":") {
m := strings.SplitN(tag, ":", 2)
t.Map[m[0]] = m[1]
} else {
t.Values = append(t.Values, tag)
}
}
}
return t
}
func appendTag(t reflect.StructTag, s string) reflect.StructTag {
ts := t.Get(ndrNameSpace)
ts = fmt.Sprintf(`%s"%s,%s"`, ndrNameSpace, ts, s)
return reflect.StructTag(ts)
}
func (t *tags) StructTag() reflect.StructTag {
mv := t.Values
for key, val := range t.Map {
mv = append(mv, key+":"+val)
}
s := ndrNameSpace + ":" + `"` + strings.Join(mv, ",") + `"`
return reflect.StructTag(s)
}
func (t *tags) delete(s string) {
for i, x := range t.Values {
if x == s {
t.Values = append(t.Values[:i], t.Values[i+1:]...)
}
}
delete(t.Map, s)
}
func (t *tags) HasValue(s string) bool {
for _, v := range t.Values {
if v == s {
return true
}
}
return false
}

57
vendor/github.com/jcmturner/rpc/v2/ndr/union.go generated vendored Normal file
View File

@ -0,0 +1,57 @@
package ndr
import (
"errors"
"fmt"
"reflect"
)
// Union interface must be implemented by structs that will be unmarshaled into from the NDR byte stream union representation.
// The union's discriminating tag will be passed to the SwitchFunc method.
// The discriminating tag field must have the struct tag: `ndr:"unionTag"`
// If the union is encapsulated the discriminating tag field must have the struct tag: `ndr:"encapsulated"`
// The possible value fields that can be selected from must have the struct tag: `ndr:"unionField"`
type Union interface {
SwitchFunc(t interface{}) string
}
// Union related constants such as struct tag values
const (
unionSelectionFuncName = "SwitchFunc"
TagEncapsulated = "encapsulated"
TagUnionTag = "unionTag"
TagUnionField = "unionField"
)
func (dec *Decoder) isUnion(field reflect.Value, tag reflect.StructTag) (r reflect.Value) {
ndrTag := parseTags(tag)
if !ndrTag.HasValue(TagUnionTag) {
return
}
r = field
// For a non-encapsulated union, the discriminant is marshalled into the transmitted data stream twice: once as the
// field or parameter, which is referenced by the switch_is construct, in the procedure argument list; and once as
// the first part of the union representation.
if !ndrTag.HasValue(TagEncapsulated) {
dec.r.Discard(int(r.Type().Size()))
}
return
}
// unionSelectedField returns the field name of which of the union values to fill
func unionSelectedField(union, discriminant reflect.Value) (string, error) {
if !union.Type().Implements(reflect.TypeOf(new(Union)).Elem()) {
return "", errors.New("struct does not implement union interface")
}
args := []reflect.Value{discriminant}
// Call the SelectFunc of the union struct to find the name of the field to fill with the value selected.
sf := union.MethodByName(unionSelectionFuncName)
if !sf.IsValid() {
return "", fmt.Errorf("could not find a selection function called %s in the unions struct representation", unionSelectionFuncName)
}
f := sf.Call(args)
if f[0].Kind() != reflect.String || f[0].String() == "" {
return "", fmt.Errorf("the union select function did not return a string for the name of the field to fill")
}
return f[0].String(), nil
}