-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Platform] kUnknownEnumValue grabs first unused enum value which need to be enforced in perpetuity #24368
Comments
We discussed this back when we introduced this, in fact, and it's fine. There are four possible scenarios when a new value is added to the spec that collides with the generated unknown value:
This all works as long as the server does not store the unknown value (which it should not, since it's not a spec-defined value). |
Not sure I agree with #3:
Lets say old client has enum:
New server has:
If the server sets the value as |
How would the server "go to read back the value"? The server can't read from the client. You're right that there is an issue if the client does a read from the server, gets "unknown value", does not check for that, and then echoes it back to the server. But the client should not be doing that, because then from its point of view it's sending a value not allowed per spec to the server.... |
I suppose one thing we could do to mitigate this is instead of looking for the first (lowest) available value pick the highest one. But just to be clear this would be mitigation only, would only help with cases where clients and/or servers are in fact violating the spec, and would not help with 100% of those cases, because enum values can get added near the end too, not just near the beginning. |
Sorry I flipped the terminology there. Swap client and server in my previous comment |
If I flip the terminology, then the server is "assigning it the value of kUnknownEnumValue". This is something servers must not do, per spec. An unknown value must either result in an error return or be treated as one of the known values if the spec defines that behavior instead. We might have some existing clusters that are buggy in that regard, and if so we should fix those ASAP. |
Let me try to outline the issue again. Because I used incorrect terminology my issue is actually with point number 4. Lets say old server has enum:
New client has:
If the client sets the value as |
Again: a spec-compliant server must not do this. It must either treat unknown values as kFirst or as error, depending on what the spec says. |
Unfortunately it looks like the current 1.0 version of the spec in SDK is doing exactly that. Interestingly enough the PR that introduce this was aware of the requirements:
Yet the PR itself added this test case expecting exactly the opposite of that stated requirement. Note the test expects a response where we are getting a return value of 4 which is Moving forward:
Edit more info:
|
We could have Encode fail for that value?
The cluster spec needs to say whether unknown values are treated as one of the known values. If it does not say anything to that effect, unknown values should be treated as invalid in incoming messages. |
The problem is that decoding 255 into a nullable enum8 is blanket disallowed by the spec (the range is defined to be 1-254), but an out-of-range enum value might need to be mapped to a valid one depending on what the cluster spec says to do. And it might say different things in different places where the enum is used. Which means that decoding cannot blanket enforce valid-only enum values. It can only collapse all invalid values into an easy-to-check-for one (which we do) and then the cluster impl needs to do the relevant checks as needed. We might be able to auto-generate checks in some cases if we express in the XML somehow what should be going on, but it might be pretty complex to do that (think enum inside struct, and two commands that take the struct but want different behavior). |
Okay we are on the same page here and this will be one of that action items for this issue.
Perhaps I should have been a little more verbose here (and also tested value 254 with the nullable enum8). What I have found in my quick testing is that I was able to write attribute value of 255 to
I see what you are saying here. But I do think the SDK needs a little more guarding for enum attributes attributes that seem to be essentially a cluster variable. It looks like |
Again: some cluster specs have text like "if an out of range value is written to this enum-typed attribute, treat it as if this in-range value had been written"... We need to make sure that can be supported by clusters and/or applications. |
…nums. This should help prevent those values leaking out on the wire. Fixes project-chip#24368
…nums. This should help prevent those values leaking out on the wire. Fixes project-chip#24368
…nums. This should help prevent those values leaking out on the wire. Fixes project-chip#24368
…nums. This should help prevent those values leaking out on the wire. Fixes project-chip#24368
…nums. This should help prevent those values leaking out on the wire. Fixes project-chip#24368
Reproduction steps
Introduced in: #20907
We are starting to see structs like this, where author adding to the enum to the xml needs to know that kUnknownEnumValue was already taken in the second spot so they intentionally skip over it:
The concern is what happens when there is a mismatch between client and server. How are we enforcing that once an enum has claimed a
kUnknownEnumValue
as a particular value that it never changes? How are people aware that when they add a new value to the end of an enum list for 1.y version that an older 1.x doesn't interpret that value askUnknownEnumValue
Platform
core (please add to version below)
Platform Version(s)
1.0
Type
Manually tested with SDK
(Optional) If manually tested please explain why this is only manually tested
No response
Anything else?
No response
The text was updated successfully, but these errors were encountered: