Skip to content

Commit 3d3f9f4

Browse files
committed
cryptobyte: don't ignore bytes added to BuilderContinuations of fixed-size Builders
Builders created with NewFixedBuilder were broken when used with BuilderContinuations. The length of the bytes written to the continuation would get added correctly to the parent, but the actual content would be discarded. For example, the BytesOrPanic() in TestFixedBuilderLengthPrefixed would return [00 08] instead of [00 08 ff ff ff ff ff ff ff ff]. Change-Id: I80837a9bf3562751addcb827274649d9f52fc79a Reviewed-on: https://go-review.googlesource.com/c/148882 Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
1 parent e4dc69e commit 3d3f9f4

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

cryptobyte/builder.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,19 @@ func (b *Builder) flushChild() {
274274
return
275275
}
276276

277-
if !b.fixedSize {
278-
b.result = child.result // In case child reallocated result.
277+
if b.fixedSize && &b.result[0] != &child.result[0] {
278+
panic("cryptobyte: BuilderContinuation reallocated a fixed-size buffer")
279279
}
280+
281+
b.result = child.result
280282
}
281283

282284
func (b *Builder) add(bytes ...byte) {
283285
if b.err != nil {
284286
return
285287
}
286288
if b.child != nil {
287-
panic("attempted write while child is pending")
289+
panic("cryptobyte: attempted write while child is pending")
288290
}
289291
if len(b.result)+len(bytes) < len(bytes) {
290292
b.err = errors.New("cryptobyte: length overflow")
@@ -304,7 +306,7 @@ func (b *Builder) Unwrite(n int) {
304306
return
305307
}
306308
if b.child != nil {
307-
panic("attempted unwrite while child is pending")
309+
panic("cryptobyte: attempted unwrite while child is pending")
308310
}
309311
length := len(b.result) - b.pendingLenLen - b.offset
310312
if length < 0 {

cryptobyte/cryptobyte_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,33 @@ func TestUnwrite(t *testing.T) {
412412
})
413413
}
414414

415+
func TestFixedBuilderLengthPrefixed(t *testing.T) {
416+
bufCap := 10
417+
inner := bytes.Repeat([]byte{0xff}, bufCap-2)
418+
buf := make([]byte, 0, bufCap)
419+
b := NewFixedBuilder(buf)
420+
b.AddUint16LengthPrefixed(func(b *Builder) {
421+
b.AddBytes(inner)
422+
})
423+
if got := b.BytesOrPanic(); len(got) != bufCap {
424+
t.Errorf("Expected output lenght to be %d, got %d", bufCap, len(got))
425+
}
426+
}
427+
428+
func TestFixedBuilderPanicReallocate(t *testing.T) {
429+
defer func() {
430+
recover()
431+
}()
432+
433+
b := NewFixedBuilder(make([]byte, 0, 10))
434+
b1 := NewFixedBuilder(make([]byte, 0, 10))
435+
b.AddUint16LengthPrefixed(func(b *Builder) {
436+
*b = *b1
437+
})
438+
439+
t.Error("Builder did not panic")
440+
}
441+
415442
// ASN.1
416443

417444
func TestASN1Int64(t *testing.T) {

0 commit comments

Comments
 (0)