diff --git a/buff.go b/buff.go index 42c6465..d1d7d24 100644 --- a/buff.go +++ b/buff.go @@ -45,6 +45,11 @@ func lineBufferFromValue(value rawValue) *lineBuilder { // WriteValue writes the given value to the lineBuilder at the give start index. func (b *lineBuilder) WriteValue(start int, value rawValue) { + // If the value is empty there is nothing to write. + if len(value.data) == 0 { + return + } + // Fast path for ascii only operation. if !b.hasMultiByteChar() && !value.hasMultiByteChar() { copy(b.data[start:], value.data) diff --git a/encode_test.go b/encode_test.go index e85510f..d1e71cf 100644 --- a/encode_test.go +++ b/encode_test.go @@ -242,6 +242,24 @@ func TestMarshal_backwardCompatibility(t *testing.T) { }) } +func TestEncoder_regressions(t *testing.T) { + // Ensure the encoder doesn't panic when encoding an empty value at the end of a line + // that contains multi-byte characters. + // See: https://github.com/ianlopshire/go-fixedwidth/issues/58 + t.Run("issue 58", func(t *testing.T) { + var v struct { + Foo string `fixed:"1,1"` + Bar string `fixed:"2,2,right"` + } + v.Foo = "Ç" + + buf := new(bytes.Buffer) + e := NewEncoder(buf) + e.SetUseCodepointIndices(true) + _ = e.Encode(v) + }) +} + func TestNewValueEncoder(t *testing.T) { for _, tt := range []struct { name string