Skip to content
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

Produce warning when enum lacks a default member. #157

Closed
andrewmd5 opened this issue Oct 5, 2021 · 0 comments
Closed

Produce warning when enum lacks a default member. #157

andrewmd5 opened this issue Oct 5, 2021 · 0 comments
Labels
enhancement New feature or request

Comments

@andrewmd5
Copy link
Contributor

andrewmd5 commented Oct 5, 2021

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 or message 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant