fix: UB casts to unspecified width enums in proto

Found by edef's fuzzing. We::jade don't think this is security-relevant
or likely to be mistreated by a compiler, but UB is bad.

https://eel.is/c++draft/expr.static.cast#8

> If the enumeration type does not have a fixed underlying type, the value is unchanged if the original value is within the range of the enumeration values ([dcl.enum]), and otherwise, the behavior is undefined

Notably, the range is defined as the smallest bitfield type that could hold all the values, not any real type which exists: https://eel.is/c++draft/dcl.enum#8.

This is basically a footgun, and I'm writing a clang-tidy check to forbid casting to such types. But first I needed to write clang-tidy testing infrastructure: https://gerrit.lix.systems/c/lix/+/5493.

Change-Id: Ieaaa0fe2a92fd9f24f60761e312741186a6a6964
This commit is contained in:
Jade Lovelace
2026-04-22 10:52:04 +00:00
committed by jade
parent 0a09782cc8
commit af99ede1fd
3 changed files with 5 additions and 6 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ struct BuildResult
* Therefore, don't remove status codes, and only add new status
* codes at the end of the list.
*/
enum Status {
enum Status : uint8_t {
Built = 0,
Substituted,
AlreadyValid,
+2 -2
View File
@@ -39,13 +39,13 @@ struct GCOptions
* Any that could not be deleted are returned via the
* `kept` field of GCResults.
*/
typedef enum {
enum GCAction : uint8_t {
gcReturnLive,
gcReturnDead,
gcDeleteDead,
gcDeleteSpecific,
gcTryDeleteSpecific,
} GCAction;
};
GCAction action{gcDeleteDead};
+2 -3
View File
@@ -35,8 +35,7 @@
namespace nix {
typedef enum {
enum Verbosity : uint8_t {
lvlError = 0,
lvlWarn,
lvlNotice,
@@ -45,7 +44,7 @@ typedef enum {
lvlChatty,
lvlDebug,
lvlVomit
} Verbosity;
};
template<>
struct json::is_integral_enum<Verbosity> : std::true_type {};