eclipse / paho.golang

Go libraries

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ValidProperties rule has some wrong. Testament message properties make connection packets include more properties.

BAN1ce opened this issue · comments

Describe the bug
Testament message properties make connection packets include more properties. I hope I could do PR, but my email can't verify. So thanks for your work.

Testament properties includes

PropPayloadFormat
PropMessageExpiry
PropContentType
PropResponseTopic
PropCorrelationData

To reproduce
Client connect to server with last will and testament, and testament Payload Format Indicator property be 1 .

Debug output
{"error": "invalid Prop type 1 for packet 1", "client": "clientID: remoteAddr: 127.0.0.1:64482"}

Expected behaviour

var ValidProperties = map[byte]map[byte]struct{}{
	PropPayloadFormat:          {CONNECT:{},PUBLISH: {}},
	PropMessageExpiry:          {CONNECT:{},PUBLISH: {}},
	PropContentType:            {CONNECT:{},PUBLISH: {}},
	PropResponseTopic:          {CONNECT:{},PUBLISH: {}},
	PropCorrelationData:        {CONNECT:{},PUBLISH: {}},
}

Apologies for the delay in looking into this. The PR you have raised addresses the issue but I wonder if there is a design problem here; we have ValidateID that checks that the property type is valid for the received packet. The issue is that the CONNECT packet has both standard properties and "Will Properties" (0x26, "User Property", could be in both, but 0x01 is valid in the "Will properties" but not "Connect Properties").

As such I wonder whether a more comprehensive solution would be better (not quite sure what that would look like). For now could you, perhaps, add a comment to the extent that the properties are only valid in WillProperties; that will mean your code works but be a reminder that we need a better way of checking this.

Yes, I know what you mean. The modified Validator cannot prevent the connect standard from containing the 0x01 property. Because the validate method only knows which message type, it is not clear which part of the properties in the message is parsed. This modification does leave hidden dangers.

I think the smaller change is to add a parameter to func (i *Properties) Unpack(r *bytes.Buffer, p byte) error as what kind of properties it is. This change may not be that small.😄
Validate's Map will also be deepened by one layer. But it’s not hard to understand. What do you think?

The packet type ID is 4 bits (so 0x00 - 0xf) but we are passing around bytes (func (i *Properties) Unpack(r *bytes.Buffer, p byte)) so an alternative would be to add something like const WillProperties= 0x7f // Dummy PacketType used to flag when Will Property is being decoded and pass that (i.e. err = c.WillProperties.Unpack(r, WillProperties). This is a bit of a hack but given this is the only packet with multiple property sets I wonder if it' ends up being easier to understand than the alternative (and without introducing a runtime performance hit).

We're currently using a generic Properties structure that encompasses all possible property types. In this scenario, it's challenging to determine which specific properties belong to each type based solely on the Properties object itself. So, the question arises: should we define distinct structures for each property type, or should we handle this distinction through external methods? What are your thoughts on this?

I believe it's crucial for us to first determine the granularity of our current validator. Should it focus on examining specific properties under each message type or only on checking the message type itself? If we opt for a more detailed approach involving each property type, it will inevitably result in a two-step verification process (with acceptable performance, in my view).

As you rightly mentioned, this approach might seem a bit unconventional. However, when we reverse our perspective, the uniqueness doesn't lie with the Connect message; rather, it's the other message types that allow multiple property types, while other message types coincidentally have only one property type.

If we can clarify the scope of the issue upfront, it will make it easier for us to identify a solution and reach a consensus.

I may be overcomplicating the problem, maybe as you said at the beginning, it is enough to add a line of comments stating that it cannot prevent the standard attribute of connect from containing the 0x01 attribute.

maybe as you said at the beginning, it is enough to add a line of comment

I feel that's an acceptable interim solution (but it's quite possible that we will never get around to implementing a more correct approach).

Yeah, So I make a comment like this. Do you think it fits?

// Notice: Connect Packet is allowed to contain the PropPayloadFormat Property,
// but it is not required. Because it has the option to include Will Properties.

Sorry - I find that a bit confusing (because CONNECT packet properties may not contain PropPayloadFormat; only the encapsulated WILL Message may).

I think a comment at the above the map would be sufficient. Maybe something like:

// A CONNECT packet has own properties, but may also include a separate set of Will Properties.
// Currently `CONNECT` covers both sets, this may lead to some invalid properties being accepted (this may be fixed in the future).

It's likely that the broker will return an error in the event that the user sends invalid properties anyway; this is more a note that we are aware of the issue and should fix it at some point.

You are right. So should I make a PR again or other way ?

You are right. So should I make a PR again or other way ?

Just push the changes to your repo and the pr should update.