// validate validates the options. func (opts *PUBLISHOptions) validate() error { // Check the QoS. if !mqtt.ValidQoS(opts.QoS) { return ErrInvalidQoS } // Check the length of the Topic Name. if len(opts.TopicName) > maxStringsLen { return ErrTopicNameExceedsMaxStringsLen } // Check if the Topic Name contains the wildcard characters. if bytes.IndexAny(opts.TopicName, wildcards) != -1 { return ErrTopicNameContainsWildcards } // Check the length of the Application Message. if len(opts.Message) > maxStringsLen { return ErrMessageExceedsMaxStringsLen } // End the validation if the QoS equals to QoS 0. if opts.QoS == mqtt.QoS0 { return nil } // Check the Packet Identifier. if opts.PacketID == 0 { return ErrInvalidPacketID } return nil }
func (opts *CONNECTOptions) validate() error { // Check the length of the Client Identifier. if len(opts.ClientID) > maxStringsLen { return ErrClientIDExceedsMaxStringsLen } // Check the combination of the Client Identifier and the Clean Session. if len(opts.ClientID) == 0 && !opts.CleanSession { return ErrInvalidClientIDCleanSession } // Check the length of the User Name. if len(opts.UserName) > maxStringsLen { return ErrUserNameExceedsMaxStringsLen } // Check the length of the Password. if len(opts.Password) > maxStringsLen { return ErrPasswordExceedsMaxStringsLen } // Check the combination of the Client Identifier and the Password. if len(opts.UserName) == 0 && len(opts.Password) > 0 { return ErrInvalidClientIDPassword } // Check the length of the Will Topic. if len(opts.WillTopic) > maxStringsLen { return ErrWillTopicExceedsMaxStringsLen } // Check the length of the Will Message. if len(opts.WillMessage) > maxStringsLen { return ErrWillMessageExceedsMaxStringsLen } // Check the combination of the Will Topic and the Will Message. if (len(opts.WillTopic) > 0 && len(opts.WillMessage) == 0) || (len(opts.WillTopic) == 0 && len(opts.WillMessage) > 0) { return ErrInvalidWillTopicMessage } // Check the Will QoS. if !mqtt.ValidQoS(opts.WillQoS) { return ErrInvalidWillQoS } // Check the combination of the Will Topic, the Will Message and the Will QoS. if len(opts.WillTopic) == 0 && len(opts.WillMessage) == 0 && opts.WillQoS != mqtt.QoS0 { return ErrInvalidWillTopicMessageQoS } // Check the combination of the Will Topic, the Will Message and the Will Retain. if len(opts.WillTopic) == 0 && len(opts.WillMessage) == 0 && opts.WillRetain { return ErrInvalidWillTopicMessageRetain } return nil }
// validateSUBACKBytes validates the fixed header and the remaining. func validateSUBACKBytes(fixedHeader FixedHeader, remaining []byte) error { // Extract the MQTT Control Packet type. ptype, err := fixedHeader.ptype() if err != nil { return err } // Check the length of the fixed header. if len(fixedHeader) < minLenSUBACKFixedHeader { return ErrInvalidFixedHeaderLen } // Check the MQTT Control Packet type. if ptype != TypeSUBACK { return ErrInvalidPacketType } // Check the reserved bits of the fixed header. if fixedHeader[0]<<4 != 0x00 { return ErrInvalidFixedHeader } // Check the length of the remaining. if len(remaining) < lenSUBACKVariableHeader+1 { return ErrInvalidRemainingLen } // Extract the Packet Identifier. packetID, _ := decodeUint16(remaining[0:lenSUBACKVariableHeader]) // Check the Packet Identifier. if packetID == 0 { return ErrInvalidPacketID } // Check each Return Code. for _, b := range remaining[lenSUBACKVariableHeader:] { if !mqtt.ValidQoS(b) && b != SUBACKRetFailure { return ErrInvalidSUBACKReturnCode } } return nil }
// validate validates the subscription request. func (s *SubReq) validate() error { // Check the length of the Topic Filter. l := len(s.TopicFilter) if l == 0 { return ErrNoTopicFilter } if l > maxStringsLen { return ErrTopicFilterExceedsMaxStringsLen } // Check the QoS. if !mqtt.ValidQoS(s.QoS) { return ErrInvalidQoS } return nil }
// validatePUBLISHBytes validates the fixed header and the variable header. func validatePUBLISHBytes(fixedHeader FixedHeader, remaining []byte) error { // Extract the MQTT Control Packet type. ptype, err := fixedHeader.ptype() if err != nil { return err } // Check the length of the fixed header. if len(fixedHeader) < minLenPUBLISHFixedHeader { return ErrInvalidFixedHeaderLen } // Check the MQTT Control Packet type. if ptype != TypePUBLISH { return ErrInvalidPacketType } // Get the QoS. qos := (fixedHeader[0] & 0x06) >> 1 // Check the QoS. if !mqtt.ValidQoS(qos) { return ErrInvalidQoS } // Check the length of the remaining. if l := len(remaining); l < minLenPUBLISHVariableHeader || l > maxRemainingLength { return ErrInvalidRemainingLen } // Extract the length of the Topic Name. lenTopicName, _ := decodeUint16(remaining[0:2]) // Calculate the length of the variable header. var lenVariableHeader int if qos == mqtt.QoS0 { lenVariableHeader = 2 + int(lenTopicName) } else { lenVariableHeader = 2 + int(lenTopicName) + 2 } // Check the length of the remaining. if len(remaining) < lenVariableHeader { return ErrInvalidRemainingLength } // End the validation if the QoS equals to QoS 0. if qos == mqtt.QoS0 { return nil } // Extract the Packet Identifier. packetID, _ := decodeUint16(remaining[2+int(lenTopicName) : 2+int(lenTopicName)+2]) // Check the Packet Identifier. if packetID == 0 { return ErrInvalidPacketID } return nil }