From b84736e9b6401df0c6eeab9950bef09458a6aefd Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Fri, 29 Sep 2017 12:46:30 -0700 Subject: Updating server dependancies. (#7538) --- vendor/golang.org/x/crypto/cryptobyte/builder.go | 84 +++++++++++++++++++----- 1 file changed, 69 insertions(+), 15 deletions(-) (limited to 'vendor/golang.org/x/crypto/cryptobyte/builder.go') diff --git a/vendor/golang.org/x/crypto/cryptobyte/builder.go b/vendor/golang.org/x/crypto/cryptobyte/builder.go index 9883fb3c3..29b4c7641 100644 --- a/vendor/golang.org/x/crypto/cryptobyte/builder.go +++ b/vendor/golang.org/x/crypto/cryptobyte/builder.go @@ -10,15 +10,25 @@ import ( ) // A Builder builds byte strings from fixed-length and length-prefixed values. +// Builders either allocate space as needed, or are ‘fixed’, which means that +// they write into a given buffer and produce an error if it's exhausted. +// // The zero value is a usable Builder that allocates space as needed. +// +// Simple values are marshaled and appended to a Builder using methods on the +// Builder. Length-prefixed values are marshaled by providing a +// BuilderContinuation, which is a function that writes the inner contents of +// the value to a given Builder. See the documentation for BuilderContinuation +// for details. type Builder struct { - err error - result []byte - fixedSize bool - child *Builder - offset int - pendingLenLen int - pendingIsASN1 bool + err error + result []byte + fixedSize bool + child *Builder + offset int + pendingLenLen int + pendingIsASN1 bool + inContinuation *bool } // NewBuilder creates a Builder that appends its output to the given buffer. @@ -86,9 +96,9 @@ func (b *Builder) AddBytes(v []byte) { // BuilderContinuation is continuation-passing interface for building // length-prefixed byte sequences. Builder methods for length-prefixed -// sequences (AddUint8LengthPrefixed etc.) will invoke the BuilderContinuation +// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation // supplied to them. The child builder passed to the continuation can be used -// to build the content of the length-prefixed sequence. Example: +// to build the content of the length-prefixed sequence. For example: // // parent := cryptobyte.NewBuilder() // parent.AddUint8LengthPrefixed(func (child *Builder) { @@ -102,8 +112,19 @@ func (b *Builder) AddBytes(v []byte) { // length prefix. After the continuation returns, the child must be considered // invalid, i.e. users must not store any copies or references of the child // that outlive the continuation. +// +// If the continuation panics with a value of type BuildError then the inner +// error will be returned as the error from Bytes. If the child panics +// otherwise then Bytes will repanic with the same value. type BuilderContinuation func(child *Builder) +// BuildError wraps an error. If a BuilderContinuation panics with this value, +// the panic will be recovered and the inner error will be returned from +// Builder.Bytes. +type BuildError struct { + Err error +} + // AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence. func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) { b.addLengthPrefixed(1, false, f) @@ -119,6 +140,34 @@ func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) { b.addLengthPrefixed(3, false, f) } +// AddUint32LengthPrefixed adds a big-endian, 32-bit length-prefixed byte sequence. +func (b *Builder) AddUint32LengthPrefixed(f BuilderContinuation) { + b.addLengthPrefixed(4, false, f) +} + +func (b *Builder) callContinuation(f BuilderContinuation, arg *Builder) { + if !*b.inContinuation { + *b.inContinuation = true + + defer func() { + *b.inContinuation = false + + r := recover() + if r == nil { + return + } + + if buildError, ok := r.(BuildError); ok { + b.err = buildError.Err + } else { + panic(r) + } + }() + } + + f(arg) +} + func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) { // Subsequent writes can be ignored if the builder has encountered an error. if b.err != nil { @@ -128,15 +177,20 @@ func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuati offset := len(b.result) b.add(make([]byte, lenLen)...) + if b.inContinuation == nil { + b.inContinuation = new(bool) + } + b.child = &Builder{ - result: b.result, - fixedSize: b.fixedSize, - offset: offset, - pendingLenLen: lenLen, - pendingIsASN1: isASN1, + result: b.result, + fixedSize: b.fixedSize, + offset: offset, + pendingLenLen: lenLen, + pendingIsASN1: isASN1, + inContinuation: b.inContinuation, } - f(b.child) + b.callContinuation(f, b.child) b.flushChild() if b.child != nil { panic("cryptobyte: internal error") -- cgit v1.2.3-1-g7c22