diff --git a/converters.go b/converters.go index ef86d95b..f73b9356 100644 --- a/converters.go +++ b/converters.go @@ -32,7 +32,9 @@ func (c *converters) parseAlphaField(r string, max uint) string { if ln > max { return r[ln-max:] } - r += strings.Repeat(" ", int(max-ln)) + if count := int(max - ln); validSize(count) { + r += strings.Repeat(" ", count) + } return r } @@ -42,7 +44,9 @@ func (c *converters) numericStringField(s string, max uint) string { if ln > max { return s[ln-max:] } - s = strings.Repeat("0", int(max-ln)) + s + if count := int(max - ln); validSize(count) { + s = strings.Repeat("0", count) + s + } return s } @@ -60,11 +64,11 @@ func (c *converters) formatAlphaField(s string, max uint, options FormatOptions) if ln > max { return s[:max] } - if !options.VariableLengthFields { - s += strings.Repeat(" ", int(max-ln)) + if count := int(max - ln); validSize(count) { + s += strings.Repeat(" ", count) + } } - return s } diff --git a/unstructuredAddenda.go b/unstructuredAddenda.go index 38ec2566..2243037e 100644 --- a/unstructuredAddenda.go +++ b/unstructuredAddenda.go @@ -73,7 +73,11 @@ func (ua *UnstructuredAddenda) String() string { buf.Grow(10) buf.WriteString(ua.tag) buf.WriteString(ua.AddendaLengthField()) - buf.Grow(ua.parseNumField(ua.AddendaLength)) + + if size := ua.parseNumField(ua.AddendaLength); validSize(size) { + buf.Grow(size) + } + buf.WriteString(ua.AddendaField()) return buf.String() } diff --git a/validators.go b/validators.go index 82c8f9b4..297eb5d0 100644 --- a/validators.go +++ b/validators.go @@ -24,6 +24,17 @@ var ( amountRegex = regexp.MustCompile("[^0-9,.]") ) +const ( + // maxBufferGrowth is the high limit for growing string builders and byte buffers. + // + // 1e8/1024/1024 is ~95MB which should be enough for anybody + maxBufferGrowth = 1e8 +) + +func validSize(n int) bool { + return n > 0 && n < maxBufferGrowth +} + // validator is common validation and formatting of golang types to WIRE type strings type validator struct{} diff --git a/validators_test.go b/validators_test.go index bf6c8bfa..e75e4db1 100644 --- a/validators_test.go +++ b/validators_test.go @@ -5,11 +5,29 @@ package wire import ( + "fmt" + "math" "testing" "github.com/stretchr/testify/require" ) +func TestValidSize(t *testing.T) { + require.True(t, validSize(10)) + require.True(t, validSize(1e7)) + + require.False(t, validSize(1e8+1)) + require.False(t, validSize(1e9)) + require.False(t, validSize(math.MaxInt)) + + t.Run("don't grow", func(t *testing.T) { + ua := &UnstructuredAddenda{} + ua.AddendaLength = fmt.Sprintf("%0.0f", 1e9) + expected := "1000" + require.Equal(t, expected, ua.String()) + }) +} + func TestValidators__validateOptionFName(t *testing.T) { v := &validator{}