This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new 3e0780b6cb fix(plc4go): correct BitBuffer EOF behavior and
empty-buffer nil semantics
3e0780b6cb is described below
commit 3e0780b6cb0df7445528cd56212448d20746e698
Author: Sebastian Rühl <[email protected]>
AuthorDate: Tue May 19 09:59:26 2026 +0200
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.
---
plc4go/spi/utils/BitBuffer.go | 8 ++++++--
plc4go/spi/utils/BitBuffer_test.go | 8 ++++----
plc4go/spi/utils/WriteBufferByteBased_test.go | 2 +-
3 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/plc4go/spi/utils/BitBuffer.go b/plc4go/spi/utils/BitBuffer.go
index 918a041dfc..31e4a9e713 100644
--- a/plc4go/spi/utils/BitBuffer.go
+++ b/plc4go/spi/utils/BitBuffer.go
@@ -85,7 +85,7 @@ func (b *ReadBitBuffer) ReadBits(n uint8) (uint64, error) {
return 0, errors.New("cannot read more than 64 bits at once")
}
if uint64(n) > b.BitsRemaining() {
- return 0, io.ErrUnexpectedEOF
+ return 0, io.EOF
}
var result uint64
@@ -134,7 +134,11 @@ type WriteBitBuffer struct {
// NewWriteBitBuffer creates a WriteBitBuffer with the given initial capacity
hint.
func NewWriteBitBuffer(initialCap int) *WriteBitBuffer {
- return &WriteBitBuffer{buf: make([]byte, 0, initialCap)}
+ var buf []byte
+ if initialCap > 0 {
+ buf = make([]byte, 0, initialCap)
+ }
+ return &WriteBitBuffer{buf: buf}
}
// WriteBool writes a single bit.
diff --git a/plc4go/spi/utils/BitBuffer_test.go
b/plc4go/spi/utils/BitBuffer_test.go
index 9b79f6bfed..05899991cd 100644
--- a/plc4go/spi/utils/BitBuffer_test.go
+++ b/plc4go/spi/utils/BitBuffer_test.go
@@ -109,7 +109,7 @@ func TestReadBitBuffer_Read(t *testing.T) {
func TestReadBitBuffer_ReadBits_EOF(t *testing.T) {
b := NewReadBitBuffer([]byte{0xFF})
_, err := b.ReadBits(9)
- assert.ErrorIs(t, err, io.ErrUnexpectedEOF)
+ assert.ErrorIs(t, err, io.EOF)
}
func TestReadBitBuffer_ReadBits_Zero(t *testing.T) {
@@ -139,7 +139,7 @@ func TestReadBitBuffer_EmptyBuffer(t *testing.T) {
b := NewReadBitBuffer([]byte{})
assert.Equal(t, uint64(0), b.BitsRemaining())
_, err := b.ReadBits(1)
- assert.ErrorIs(t, err, io.ErrUnexpectedEOF)
+ assert.ErrorIs(t, err, io.EOF)
}
func TestReadBitBuffer_Read_Partial(t *testing.T) {
@@ -240,14 +240,14 @@ func TestWriteBitBuffer_TryWriteByte(t *testing.T) {
func TestWriteBitBuffer_WriteBits_Zero(t *testing.T) {
w := NewWriteBitBuffer(0)
require.NoError(t, w.WriteBits(0xFF, 0))
- assert.Equal(t, []byte{}, w.Bytes())
+ assert.Nil(t, w.Bytes())
}
func TestWriteBitBuffer_WriteBits_TooMany(t *testing.T) {
w := NewWriteBitBuffer(0)
err := w.WriteBits(0, 65)
require.Error(t, err)
- assert.Equal(t, []byte{}, w.Bytes(), "buffer must not change on error")
+ assert.Nil(t, w.Bytes(), "buffer must not change on error")
}
func TestWriteBitBuffer_WriteBits_64(t *testing.T) {
diff --git a/plc4go/spi/utils/WriteBufferByteBased_test.go
b/plc4go/spi/utils/WriteBufferByteBased_test.go
index 8916562f84..adcc594618 100644
--- a/plc4go/spi/utils/WriteBufferByteBased_test.go
+++ b/plc4go/spi/utils/WriteBufferByteBased_test.go
@@ -166,7 +166,7 @@ func Test_byteWriteBuffer_GetBytes(t *testing.T) {
fields: fields{
bits: NewWriteBitBuffer(0),
},
- want: []byte{},
+ want: nil,
},
}
for _, tt := range tests {