Skip to content

Commit

Permalink
fix parsing responses with returned byte count overflowing uint8 value
Browse files Browse the repository at this point in the history
  • Loading branch information
aldas committed Apr 5, 2021
1 parent e184084 commit 03b4c8d
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 20 deletions.
10 changes: 5 additions & 5 deletions packet/readcoilsresponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func ParseReadCoilsResponseTCP(data []byte) (*ReadCoilsResponseTCP, error) {
if dLen < 10 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[8]
if dLen != 9+int(byteLen) {
byteLen := int(data[8])
if dLen != 9+byteLen {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadCoilsResponseTCP{
Expand All @@ -66,7 +66,7 @@ func ParseReadCoilsResponseTCP(data []byte) (*ReadCoilsResponseTCP, error) {
ReadCoilsResponse: ReadCoilsResponse{
UnitID: data[6],
// function code = data[7]
CoilsByteLength: byteLen,
CoilsByteLength: data[8],
Data: data[9 : 9+byteLen],
},
}, nil
Expand All @@ -89,8 +89,8 @@ func ParseReadCoilsResponseRTU(data []byte) (*ReadCoilsResponseRTU, error) {
if dLen < 6 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[2]
if dLen != 3+int(byteLen)+2 {
byteLen := int(data[2])
if dLen != 3+byteLen+2 {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadCoilsResponseRTU{
Expand Down
32 changes: 32 additions & 0 deletions packet/readcoilsresponse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func TestReadCoilsResponseTCP_Bytes(t *testing.T) {
}

func TestParseReadCoilsResponseTCP(t *testing.T) {
max124registers := make([]byte, 248)

var testCases = []struct {
name string
given []byte
Expand Down Expand Up @@ -84,6 +86,21 @@ func TestParseReadCoilsResponseTCP(t *testing.T) {
given: []byte{0x81, 0x80, 0x00, 0x00, 0x00, 0x05, 0x03, 0x01, 0x01, 0xCD, 0x6B},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: append([]byte{0x81, 0x80, 0x00, 0x00, 0x00, 0x05, 0x03, 0x01, 248}, max124registers...),
expect: &ReadCoilsResponseTCP{
MBAPHeader: MBAPHeader{
TransactionID: 33152,
ProtocolID: 0,
},
ReadCoilsResponse: ReadCoilsResponse{
UnitID: 3,
CoilsByteLength: 248,
Data: max124registers,
},
},
},
}

for _, tc := range testCases {
Expand Down Expand Up @@ -128,6 +145,21 @@ func TestParseReadCoilsResponseRTU(t *testing.T) {
given: []byte{0x10, 0x1, 0x1, 0x1, 0x2, 0xec, 0xd2},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: func() []byte {
max124registers := make([]byte, 248)
b := append([]byte{0x03, 0x01, 248}, max124registers...)
return append(b, []byte{0xff, 0xff}...) // + CRC (invalid crc)
}(),
expect: &ReadCoilsResponseRTU{
ReadCoilsResponse: ReadCoilsResponse{
UnitID: 3,
CoilsByteLength: 248,
Data: make([]byte, 248),
},
},
},
}

for _, tc := range testCases {
Expand Down
8 changes: 4 additions & 4 deletions packet/readdiscreteinputsresponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func ParseReadDiscreteInputsResponseTCP(data []byte) (*ReadDiscreteInputsRespons
if dLen < 10 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[8]
if dLen != 9+int(byteLen) {
byteLen := int(data[8])
if dLen != 9+byteLen {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadDiscreteInputsResponseTCP{
Expand Down Expand Up @@ -89,8 +89,8 @@ func ParseReadDiscreteInputsResponseRTU(data []byte) (*ReadDiscreteInputsRespons
if dLen < 6 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[2]
if dLen != 3+int(byteLen)+2 {
byteLen := int(data[2])
if dLen != 3+byteLen+2 {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadDiscreteInputsResponseRTU{
Expand Down
32 changes: 32 additions & 0 deletions packet/readdiscreteinputsresponse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func TestReadDiscreteInputsResponseTCP_Bytes(t *testing.T) {
}

func TestParseReadDiscreteInputsResponseTCP(t *testing.T) {
max124registers := make([]byte, 248)

var testCases = []struct {
name string
given []byte
Expand Down Expand Up @@ -84,6 +86,21 @@ func TestParseReadDiscreteInputsResponseTCP(t *testing.T) {
given: []byte{0x81, 0x80, 0x00, 0x00, 0x00, 0x05, 0x03, 0x01, 0x01, 0xCD, 0x6B},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: append([]byte{0x81, 0x80, 0x00, 0x00, 0x00, 0x05, 0x03, 0x02, 248}, max124registers...),
expect: &ReadDiscreteInputsResponseTCP{
MBAPHeader: MBAPHeader{
TransactionID: 33152,
ProtocolID: 0,
},
ReadDiscreteInputsResponse: ReadDiscreteInputsResponse{
UnitID: 3,
InputsByteLength: 248,
Data: max124registers,
},
},
},
}

for _, tc := range testCases {
Expand Down Expand Up @@ -128,6 +145,21 @@ func TestParseReadDiscreteInputsResponseRTU(t *testing.T) {
given: []byte{0x10, 0x1, 0x1, 0x1, 0x2, 0xec, 0xd2},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: func() []byte {
max124registers := make([]byte, 248)
b := append([]byte{0x03, 0x02, 248}, max124registers...)
return append(b, []byte{0xff, 0xff}...) // + CRC (invalid crc)
}(),
expect: &ReadDiscreteInputsResponseRTU{
ReadDiscreteInputsResponse: ReadDiscreteInputsResponse{
UnitID: 3,
InputsByteLength: 248,
Data: make([]byte, 248),
},
},
},
}

for _, tc := range testCases {
Expand Down
4 changes: 2 additions & 2 deletions packet/readholdingregistersresponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ func ParseReadHoldingRegistersResponseRTU(data []byte) (*ReadHoldingRegistersRes
if dLen < 7 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[2]
if dLen != 3+int(byteLen)+2 {
byteLen := int(data[2])
if dLen != 3+byteLen+2 {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadHoldingRegistersResponseRTU{
Expand Down
15 changes: 15 additions & 0 deletions packet/readholdingregistersresponse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,21 @@ func TestParseReadHoldingRegistersResponseRTU(t *testing.T) {
given: []byte{0x10, 0x3, 0x1, 0x1, 0x2, 0xe, 0xd3},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: func() []byte {
max124registers := make([]byte, 248)
b := append([]byte{0x03, 0x03, 248}, max124registers...)
return append(b, []byte{0xff, 0xff}...) // + CRC (invalid crc)
}(),
expect: &ReadHoldingRegistersResponseRTU{
ReadHoldingRegistersResponse: ReadHoldingRegistersResponse{
UnitID: 3,
RegisterByteLen: 248,
Data: make([]byte, 248),
},
},
},
}

for _, tc := range testCases {
Expand Down
10 changes: 5 additions & 5 deletions packet/readinputregistersresponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func ParseReadInputRegistersResponseTCP(data []byte) (*ReadInputRegistersRespons
if dLen < 11 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[8]
if dLen != 9+int(byteLen) {
byteLen := int(data[8])
if dLen != 9+byteLen {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadInputRegistersResponseTCP{
Expand All @@ -67,7 +67,7 @@ func ParseReadInputRegistersResponseTCP(data []byte) (*ReadInputRegistersRespons
UnitID: data[6],
// function code = data[7]
RegisterByteLen: data[8],
Data: data[9:],
Data: data[9 : 9+byteLen],
},
}, nil
}
Expand All @@ -89,8 +89,8 @@ func ParseReadInputRegistersResponseRTU(data []byte) (*ReadInputRegistersRespons
if dLen < 7 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[2]
if dLen != 3+int(byteLen)+2 {
byteLen := int(data[2])
if dLen != 3+byteLen+2 {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadInputRegistersResponseRTU{
Expand Down
32 changes: 32 additions & 0 deletions packet/readinputregistersresponse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func TestReadInputRegistersResponseTCP_Bytes(t *testing.T) {
}

func TestParseReadInputRegistersResponseTCP(t *testing.T) {
max124registers := make([]byte, 248)

var testCases = []struct {
name string
given []byte
Expand Down Expand Up @@ -84,6 +86,21 @@ func TestParseReadInputRegistersResponseTCP(t *testing.T) {
given: []byte{0x81, 0x80, 0x00, 0x00, 0x00, 0x05, 0x03, 0x04, 0x01, 0xCD, 0x6B},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: append([]byte{0x81, 0x80, 0x00, 0x00, 0x00, 0x05, 0x03, 0x04, 248}, max124registers...),
expect: &ReadInputRegistersResponseTCP{
MBAPHeader: MBAPHeader{
TransactionID: 33152,
ProtocolID: 0,
},
ReadInputRegistersResponse: ReadInputRegistersResponse{
UnitID: 3,
RegisterByteLen: 248,
Data: max124registers,
},
},
},
}

for _, tc := range testCases {
Expand Down Expand Up @@ -128,6 +145,21 @@ func TestParseReadInputRegistersResponseRTU(t *testing.T) {
given: []byte{0x10, 0x4, 0x1, 0x1, 0x2, 0xb9, 0xd2},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: func() []byte {
max124registers := make([]byte, 248)
b := append([]byte{0x03, 0x04, 248}, max124registers...)
return append(b, []byte{0xff, 0xff}...) // + CRC (invalid crc)
}(),
expect: &ReadInputRegistersResponseRTU{
ReadInputRegistersResponse: ReadInputRegistersResponse{
UnitID: 3,
RegisterByteLen: 248,
Data: make([]byte, 248),
},
},
},
}

for _, tc := range testCases {
Expand Down
8 changes: 4 additions & 4 deletions packet/readwritemultipleregistersresponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func ParseReadWriteMultipleRegistersResponseTCP(data []byte) (*ReadWriteMultiple
if dLen < 11 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[8]
if dLen != 9+int(byteLen) {
byteLen := int(data[8])
if dLen != 9+byteLen {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadWriteMultipleRegistersResponseTCP{
Expand Down Expand Up @@ -89,8 +89,8 @@ func ParseReadWriteMultipleRegistersResponseRTU(data []byte) (*ReadWriteMultiple
if dLen < 7 {
return nil, errors.New("received data length too short to be valid packet")
}
byteLen := data[2]
if dLen != 3+int(byteLen)+2 {
byteLen := int(data[2])
if dLen != 3+byteLen+2 {
return nil, errors.New("received data length does not match byte len in packet")
}
return &ReadWriteMultipleRegistersResponseRTU{
Expand Down
32 changes: 32 additions & 0 deletions packet/readwritemultipleregistersresponse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func TestReadWriteMultipleRegistersResponseTCP_Bytes(t *testing.T) {
}

func TestParseReadWriteMultipleRegistersResponseTCP(t *testing.T) {
max124registers := make([]byte, 248)

var testCases = []struct {
name string
given []byte
Expand Down Expand Up @@ -84,6 +86,21 @@ func TestParseReadWriteMultipleRegistersResponseTCP(t *testing.T) {
given: []byte{0x81, 0x80, 0x00, 0x00, 0x00, 0x05, 0x03, 0x17, 0x01, 0xCD, 0x6B},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: append([]byte{0x81, 0x80, 0x00, 0x00, 0x00, 0x05, 0x03, 0x04, 248}, max124registers...),
expect: &ReadWriteMultipleRegistersResponseTCP{
MBAPHeader: MBAPHeader{
TransactionID: 33152,
ProtocolID: 0,
},
ReadWriteMultipleRegistersResponse: ReadWriteMultipleRegistersResponse{
UnitID: 3,
RegisterByteLen: 248,
Data: max124registers,
},
},
},
}

for _, tc := range testCases {
Expand Down Expand Up @@ -128,6 +145,21 @@ func TestParseReadWriteMultipleRegistersResponseRTU(t *testing.T) {
given: []byte{0x10, 0x17, 0x1, 0x1, 0x2, 0xe, 0xd3},
expectError: "received data length does not match byte len in packet",
},
{
name: "ok, length is at the edge max byte/uint8 value",
given: func() []byte {
max124registers := make([]byte, 248)
b := append([]byte{0x03, 0x17, 248}, max124registers...)
return append(b, []byte{0xff, 0xff}...) // + CRC (invalid crc)
}(),
expect: &ReadWriteMultipleRegistersResponseRTU{
ReadWriteMultipleRegistersResponse: ReadWriteMultipleRegistersResponse{
UnitID: 3,
RegisterByteLen: 248,
Data: make([]byte, 248),
},
},
},
}

for _, tc := range testCases {
Expand Down

0 comments on commit 03b4c8d

Please sign in to comment.