1010class QModbusAduRtu : public QModbusAdu
1111{
1212public:
13+ // / Minimum RTU frame size: address(1) + function(1) + data(0+) + CRC(2)
14+ static constexpr int MinRtuFrameSize = 4 ;
15+
1316 explicit QModbusAduRtu (const QByteArray& rawData)
1417 : QModbusAdu()
1518 {
@@ -21,6 +24,8 @@ class QModbusAduRtu : public QModbusAdu
2124 // / \return
2225 // /
2326 bool isValid () const override {
27+ if (_data.size () < MinRtuFrameSize)
28+ return false ;
2429 return matchingChecksum () && _pdu.isValid ();
2530 }
2631
@@ -30,15 +35,23 @@ class QModbusAduRtu : public QModbusAdu
3035 // /
3136 void setRawData (const QByteArray& data) override {
3237 _data = data;
33- _pdu.setFunctionCode (QModbusPdu::FunctionCode ((quint8)_data[1 ]));
34- _pdu.setData (_data.mid (2 , _data.size () - 4 ));
38+ if (_data.size () >= MinRtuFrameSize) {
39+ _pdu.setFunctionCode (QModbusPdu::FunctionCode (quint8 (_data[1 ])));
40+ _pdu.setData (_data.mid (2 , _data.size () - MinRtuFrameSize));
41+ } else {
42+ _pdu.setFunctionCode (QModbusPdu::Invalid); // reset to invalid state
43+ _pdu.setData (QByteArray ());
44+ }
3545 }
3646
3747 // /
3848 // / \brief serverAddress
3949 // / \return
4050 // /
4151 quint8 serverAddress () const override {
52+ if (_data.isEmpty ())
53+ return 0 ;
54+
4255 return quint8 (_data[0 ]);
4356 }
4457
@@ -47,17 +60,23 @@ class QModbusAduRtu : public QModbusAdu
4760 // / \return
4861 // /
4962 quint16 checksum () const {
50- return makeUInt16 (_data[_data.size () - 1 ], _data[_data.size () - 2 ], ByteOrder::Direct);
63+ if (_data.size () >= MinRtuFrameSize) {
64+ return makeUInt16 (_data[_data.size () - 1 ], _data[_data.size () - 2 ], ByteOrder::Direct);
65+ }
66+ return 0 ;
5167 }
5268
5369 // /
5470 // / \brief calcChecksum
5571 // / \return
5672 // /
5773 quint16 calcChecksum () const {
58- const auto size = _data.size () - 2 ; // two bytes, CRC
59- const auto data = _data.left (size);
60- return calculateCRC (data, size);
74+ if (_data.size () < MinRtuFrameSize)
75+ return 0 ;
76+
77+ const int crcDataSize = _data.size () - 2 ;
78+ const QByteArray crcData = _data.left (crcDataSize);
79+ return calculateCRC (crcData.constData (), crcDataSize);
6180 }
6281
6382 // /
@@ -68,7 +87,10 @@ class QModbusAduRtu : public QModbusAdu
6887 return checksum () == calcChecksum ();
6988 }
7089
71- inline static quint16 calculateCRC (const char * data, qint32 len){
90+ inline static quint16 calculateCRC (const char * data, qint32 len) {
91+ if (len <= 0 || data == nullptr )
92+ return 0 ;
93+
7294 quint16 crc = 0xFFFF ;
7395 while (len--) {
7496 const quint8 c = *data++;
@@ -82,12 +104,12 @@ class QModbusAduRtu : public QModbusAdu
82104 }
83105 crc &= 0xFFFF ;
84106 }
85- crc = crc_reflect (crc & 0xFFFF , 16 ) ^ 0x0000 ;
86- return (crc >> 8 ) | (crc << 8 ); // swap bytes
107+ crc = crc_reflect (crc, 16 );
108+ return (crc >> 8 ) | (crc << 8 ); // swap bytes
87109 }
88110
89111private:
90- inline static quint16 crc_reflect (quint16 data, qint32 len){
112+ inline static quint16 crc_reflect (quint16 data, qint32 len) {
91113 quint16 ret = data & 0x01 ;
92114 for (qint32 i = 1 ; i < len; i++) {
93115 data >>= 1 ;
0 commit comments