Produce warning when enum lacks a default member.
andrewmd5 opened this issue · comments
Is your feature request related to a problem? Please describe.
Because code generated by bebopc is designed to be fast decoding of an enum is essentially just an unchecked cast of an integral value to the runtime representation of the enum.
For instance, in this enum:
enum Color { Red = 1; Green = 2; Blue = 3; }
Casting 1
to Color
would result in Color.Red
. However if for some reason a value such as 4
was read from the buffer, because the generated code may be subject to language-specific implementation details, the language may choose to not throw and cast 4
to Color.Red
or default to 0
(even if it is not defined) which leads to undefined behavior.
This may sound fine initially, until you realize exploits like OMIGOD were caused due to the combination of a simple conditional statement coding mistake and an uninitialized auth struct, which meant any request without an Authorization
header had its privileges default to uid=0, gid=0, which is root.
So if someone defined the following schema:
enum UserGroup { Root = 0; Limited = 1; Test = 2; }
readonly struct User {
UserGroup group;
uint32 id;
}
Calling new User()
would be enough to create a new and valid instance that could be encoded and subsequently decoded by a sensitive system without producing a single runtime error. A modification to the buffer that holds the encoded enum value could also be modified (either purposefully or due to corruption) to have a value not defined in the constant which may be casted to the default value of the enum (in this case 0
).
In both examples whether by human error or improper validation of input data a program may believe the user is now root, again without raising any runtime errors.
Describe the solution you'd like
When generating code if an enum does not define a Default
member a warning should be produced. Because of #156 the Default
member should be the default value of the integral chosen. So for an enum with a backing type of uint32
that is 0
but for one using int32
it is -1
.
It would look like this:
enum UserGroup { Default = 0; Root =1; Limited = 2; Test = 3; }
This would let people know they're defining an enum that could create undefined behavior. This warning would be silenced if the a member is assigned the default value of the integral chosen with a name such as Invalid
or Unknown
to respect common patterns.
Describe alternatives you've considered
- Making
Default
a reserved enum member that is automatically placed into generated code. This is an extreme option however and would map mapping existing enums difficult. - Creating an attribute that can be placed on a
struct
ormessage
that would enable stricter checks when encoding / decoding an enum in the generated code on a per-type basis.
Additional context
The VS code plugin should be able to show warnings as well.