Skip to content

Commit 3e0780b

Browse files
committed
fix(plc4go): correct BitBuffer EOF behavior and empty-buffer nil semantics
ReadBits returned io.ErrUnexpectedEOF on exhaustion, but the old bitio library returned io.EOF. ReadOptionalField only catches io.EOF to detect absent optional fields, so the wrong sentinel caused parse errors in the CBUS MMI path (CALData additionalData recursion hit EOF and propagated instead of being silently absent). NewWriteBitBuffer(0) initialised buf with make([]byte,0,0), producing a non-nil empty slice where the old bytes.Buffer returned nil for an empty buffer. Serialising an empty object now correctly returns nil again.
1 parent dbd320a commit 3e0780b

3 files changed

Lines changed: 11 additions & 7 deletions

File tree

plc4go/spi/utils/BitBuffer.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (b *ReadBitBuffer) ReadBits(n uint8) (uint64, error) {
8585
return 0, errors.New("cannot read more than 64 bits at once")
8686
}
8787
if uint64(n) > b.BitsRemaining() {
88-
return 0, io.ErrUnexpectedEOF
88+
return 0, io.EOF
8989
}
9090

9191
var result uint64
@@ -134,7 +134,11 @@ type WriteBitBuffer struct {
134134

135135
// NewWriteBitBuffer creates a WriteBitBuffer with the given initial capacity hint.
136136
func NewWriteBitBuffer(initialCap int) *WriteBitBuffer {
137-
return &WriteBitBuffer{buf: make([]byte, 0, initialCap)}
137+
var buf []byte
138+
if initialCap > 0 {
139+
buf = make([]byte, 0, initialCap)
140+
}
141+
return &WriteBitBuffer{buf: buf}
138142
}
139143

140144
// WriteBool writes a single bit.

plc4go/spi/utils/BitBuffer_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func TestReadBitBuffer_Read(t *testing.T) {
109109
func TestReadBitBuffer_ReadBits_EOF(t *testing.T) {
110110
b := NewReadBitBuffer([]byte{0xFF})
111111
_, err := b.ReadBits(9)
112-
assert.ErrorIs(t, err, io.ErrUnexpectedEOF)
112+
assert.ErrorIs(t, err, io.EOF)
113113
}
114114

115115
func TestReadBitBuffer_ReadBits_Zero(t *testing.T) {
@@ -139,7 +139,7 @@ func TestReadBitBuffer_EmptyBuffer(t *testing.T) {
139139
b := NewReadBitBuffer([]byte{})
140140
assert.Equal(t, uint64(0), b.BitsRemaining())
141141
_, err := b.ReadBits(1)
142-
assert.ErrorIs(t, err, io.ErrUnexpectedEOF)
142+
assert.ErrorIs(t, err, io.EOF)
143143
}
144144

145145
func TestReadBitBuffer_Read_Partial(t *testing.T) {
@@ -240,14 +240,14 @@ func TestWriteBitBuffer_TryWriteByte(t *testing.T) {
240240
func TestWriteBitBuffer_WriteBits_Zero(t *testing.T) {
241241
w := NewWriteBitBuffer(0)
242242
require.NoError(t, w.WriteBits(0xFF, 0))
243-
assert.Equal(t, []byte{}, w.Bytes())
243+
assert.Nil(t, w.Bytes())
244244
}
245245

246246
func TestWriteBitBuffer_WriteBits_TooMany(t *testing.T) {
247247
w := NewWriteBitBuffer(0)
248248
err := w.WriteBits(0, 65)
249249
require.Error(t, err)
250-
assert.Equal(t, []byte{}, w.Bytes(), "buffer must not change on error")
250+
assert.Nil(t, w.Bytes(), "buffer must not change on error")
251251
}
252252

253253
func TestWriteBitBuffer_WriteBits_64(t *testing.T) {

plc4go/spi/utils/WriteBufferByteBased_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func Test_byteWriteBuffer_GetBytes(t *testing.T) {
166166
fields: fields{
167167
bits: NewWriteBitBuffer(0),
168168
},
169-
want: []byte{},
169+
want: nil,
170170
},
171171
}
172172
for _, tt := range tests {

0 commit comments

Comments
 (0)