From 838991638a7f798354f9748bc3f12218557ea615 Mon Sep 17 00:00:00 2001 From: Alexander Yastrebov Date: Sat, 30 Oct 2021 20:35:10 +0200 Subject: [PATCH] x/crypto: add ReadUint32LengthPrefixed Fixes golang/go#49227 --- cryptobyte/cryptobyte_test.go | 21 +++++++++++++++++++++ cryptobyte/string.go | 11 ++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/cryptobyte/cryptobyte_test.go b/cryptobyte/cryptobyte_test.go index fb63709148..d3717a3b62 100644 --- a/cryptobyte/cryptobyte_test.go +++ b/cryptobyte/cryptobyte_test.go @@ -305,6 +305,27 @@ func TestUint8LengthPrefixedNested(t *testing.T) { } } +func TestUint32LengthPrefixedSimple(t *testing.T) { + var b Builder + b.AddUint32LengthPrefixed(func(c *Builder) { + c.AddUint8(23) + c.AddUint8(42) + }) + if err := builderBytesEq(&b, 0, 0, 0, 2, 23, 42); err != nil { + t.Error(err) + } + var s, out String = String(b.BytesOrPanic()), nil + if !s.ReadUint32LengthPrefixed(&out) { + t.Error("read failed") + } + if len(out) != 2 || out[0] != 23 || out[1] != 42 { + t.Error("read incorrect value") + } + if len(s) != 0 { + t.Error("incorrect source length") + } +} + func TestPreallocatedBuffer(t *testing.T) { var buf [5]byte b := NewBuilder(buf[0:0]) diff --git a/cryptobyte/string.go b/cryptobyte/string.go index 589d297e6b..ade0e4e26c 100644 --- a/cryptobyte/string.go +++ b/cryptobyte/string.go @@ -105,7 +105,8 @@ func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool { length = length << 8 length = length | uint32(b) } - v := s.read(int(length)) + n := int(length) + v := s.read(n) // returns nil if n is negative due to overflow if v == nil { return false } @@ -133,6 +134,14 @@ func (s *String) ReadUint24LengthPrefixed(out *String) bool { return s.readLengthPrefixed(3, out) } +// ReadUint32LengthPrefixed reads the content of a big-endian, 32-bit +// length-prefixed value into out and advances over it. It reports whether +// the read was successful. +// On 32-bit platform read fails if length is greater than max int. +func (s *String) ReadUint32LengthPrefixed(out *String) bool { + return s.readLengthPrefixed(4, out) +} + // ReadBytes reads n bytes into out and advances over them. It reports // whether the read was successful. func (s *String) ReadBytes(out *[]byte, n int) bool {