Skip to content

Why should 0 be a "boring" value in an enum?

Lynn edited this page Feb 2, 2022 · 2 revisions

Why should 0 be a "boring" value in an enum?

Bebop makes the unusual choice of being opinionated about what the 0 member of an enum is called.

For all but a select set of identifiers, it issues a warning like so:

Bebop recommends that 0 in an enum be reserved for a value named Unknown, Default, or similar.

(You can disable this warning with the --no-warn 200 compiler flag.)

The full list of acceptable names is: "Default", "Unknown", "Invalid", "Null", "None", "Zero", "False".

But why?

The reason

This warning was inspired by news of the OMIGOD vulnerability, where an attacker could achieve root privileges because of a bug involving an uninitialized "authInfo" struct in a C program.

Before this fix, the uninitialized uid and gid values were filled with… zero. (The memory here was allocated by calloc.) And uid=0 gid=0 happens to mean "root"!

This sort of bug is easy to write, and OMIGOD is far from an isolated incident. As long as there are popular languages where it's easy for memory to accidentally be zeroed out, we believe there's a security benefit in ensuring that 0 always means something boring.

That's why Bebop encourages you to leave 0 explicitly reserved to mean "invalid" or "default", and starting the "interesting" values from 1.

Discouraged Encouraged
enum UserType {
    Admin = 0;  // uh-oh
    Musician = 1;
    Listener = 2;
}
enum UserType {
    Invalid = 0;  // whew!
    Admin = 1;
    Musician = 2;
    Listener = 3;
}