@@ -977,29 +977,49 @@ ConnAckData MqttPacket::parseConnAckData()
977977 result.session_expire = std::min<uint32_t >(readFourBytesToUint32 (), result.session_expire );
978978 break ;
979979 case Mqtt5Properties::ReceiveMaximum:
980+ {
980981 if (pcounts[1 ]++ > 0 )
981982 throw ProtocolError (" Can't specify " + propertyToString (prop) + " more than once" , ReasonCodes::ProtocolError);
982983
983- result.client_receive_max = std::min<uint16_t >(readTwoBytesToUInt16 (), result.client_receive_max );
984+ const uint16_t val{readTwoBytesToUInt16 ()};
985+ if (val == 0 )
986+ throw ProtocolError (" In CONNACK: ReceiveMax can't be 0" , ReasonCodes::ProtocolError);
987+ result.client_receive_max = std::min<uint16_t >(val, result.client_receive_max );
984988 break ;
989+ }
985990 case Mqtt5Properties::MaximumQoS:
991+ {
986992 if (pcounts[2 ]++ > 0 )
987993 throw ProtocolError (" Can't specify " + propertyToString (prop) + " more than once" , ReasonCodes::ProtocolError);
988994
989- result.max_qos = std::min<uint8_t >(readUint8 (), result.max_qos );
995+ const uint8_t val {readUint8 ()};
996+ if (val > 2 )
997+ throw ProtocolError (" In CONNACK: QoS must be <= 2" , ReasonCodes::ProtocolError);
998+ result.max_qos = std::min<uint8_t >(val, result.max_qos );
990999 break ;
1000+ }
9911001 case Mqtt5Properties::RetainAvailable:
1002+ {
9921003 if (pcounts[3 ]++ > 0 )
9931004 throw ProtocolError (" Can't specify " + propertyToString (prop) + " more than once" , ReasonCodes::ProtocolError);
9941005
995- result.retained_available = static_cast <bool >(readByte ());
1006+ const uint8_t val{readUint8 ()};
1007+ if (val > 1 )
1008+ throw ProtocolError (" In CONNACK: RetainAvailable must be <= 1" , ReasonCodes::ProtocolError);
1009+ result.retained_available = static_cast <bool >(val);
9961010 break ;
1011+ }
9971012 case Mqtt5Properties::MaximumPacketSize:
1013+ {
9981014 if (pcounts[4 ]++ > 0 )
9991015 throw ProtocolError (" Can't specify " + propertyToString (prop) + " more than once" , ReasonCodes::ProtocolError);
10001016
1001- result.max_outgoing_packet_size = std::min<uint32_t >(readFourBytesToUint32 (), result.max_outgoing_packet_size );
1017+ const uint32_t val {readFourBytesToUint32 ()};
1018+ if (val == 0 )
1019+ throw ProtocolError (" In CONNACK: MaximumPacketSize must be > 0" , ReasonCodes::ProtocolError);
1020+ result.max_outgoing_packet_size = std::min<uint32_t >(val, result.max_outgoing_packet_size );
10021021 break ;
1022+ }
10031023 case Mqtt5Properties::AssignedClientIdentifier:
10041024 if (pcounts[5 ]++ > 0 )
10051025 throw ProtocolError (" Can't specify " + propertyToString (prop) + " more than once" , ReasonCodes::ProtocolError);
@@ -1039,11 +1059,16 @@ ConnAckData MqttPacket::parseConnAckData()
10391059 readByte ();
10401060 break ;
10411061 case Mqtt5Properties::SharedSubscriptionAvailable:
1062+ {
10421063 if (pcounts[10 ]++ > 0 )
10431064 throw ProtocolError (" Can't specify " + propertyToString (prop) + " more than once" , ReasonCodes::ProtocolError);
10441065
1045- result.shared_subscriptions_available = !!readByte ();
1066+ const uint8_t val{readUint8 ()};
1067+ if (val > 1 )
1068+ throw ProtocolError (" In CONNACK: SharedSubscriptionAvailable must be <= 1" , ReasonCodes::ProtocolError);
1069+ result.shared_subscriptions_available = static_cast <bool >(val);
10461070 break ;
1071+ }
10471072 case Mqtt5Properties::ServerKeepAlive:
10481073 if (pcounts[11 ]++ > 0 )
10491074 throw ProtocolError (" Can't specify " + propertyToString (prop) + " more than once" , ReasonCodes::ProtocolError);
0 commit comments