Add underlying type to Balsa enums. Otherwise the static_cast<ParseState>(-1) in HTTPBalsaFrame.ParseStateToString in balsa_frame_test.cc is undefined behavior. The C++ standard states: "A value of integral or enumeration type can be explicitly converted to a complete enumeration type. If the enumeration type has a fixed underlying type, the value is [...] converted [...] to the enumeration type. 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, and otherwise, the behavior is undefined." See https://github.com/cplusplus/draft/blob/193a67c9f17e3d7102061e8e01250562b6292351/source/expressions.tex#L4005-L4017 (The actual standard is not available for free, this is an official draft.) In other words, conversion of any value is well-defined if the enum has an underlying type, but not otherwise. I can reproduce by compiling the following example: enum ParseState { A, B, C, }; int main() { ParseState state = static_cast<ParseState>(8); return state + 2; } clang enum.cc -fsanitize=undefined -l:libstdc++.a && ./a.out enum.cc:11:10: runtime error: load of value 8, which is not a valid value for type 'ParseState' SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior enum.cc:11:10 in And if I add ParseState : int, the error goes away. This was caught by Envoy ASAN CI, and is blocking Balsa integration to Envoy. See https://dev.azure.com/cncf/envoy/_build/results?buildId=108238&view=logs&j=1439b9f7-a348-5b50-b5fe-ea612ea91241&t=37b0a9be-1a71-50b3-594a-4c04a031247d. Once here, add underlying type to all enums in balsa_enums.h. PiperOrigin-RevId: 448474661
diff --git a/quiche/balsa/balsa_enums.h b/quiche/balsa/balsa_enums.h index 2c067b6..9302881 100644 --- a/quiche/balsa/balsa_enums.h +++ b/quiche/balsa/balsa_enums.h
@@ -10,7 +10,7 @@ namespace quiche { struct QUICHE_EXPORT_PRIVATE BalsaFrameEnums { - enum ParseState { + enum ParseState : int { ERROR, READING_HEADER_AND_FIRSTLINE, READING_CHUNK_LENGTH, @@ -25,7 +25,7 @@ NUM_STATES, }; - enum ErrorCode { + enum ErrorCode : int { // A sentinel value for convenience, none of the callbacks should ever see // this error code. NO_ERROR = 0, @@ -113,7 +113,7 @@ }; struct QUICHE_EXPORT_PRIVATE BalsaHeadersEnums { - enum ContentLengthStatus { + enum ContentLengthStatus : int { INVALID_CONTENT_LENGTH, CONTENT_LENGTH_OVERFLOW, NO_CONTENT_LENGTH,