From f2fff1faa4c6a308ad30da691e18ceccf6626e0d Mon Sep 17 00:00:00 2001 From: Jade Lovelace Date: Tue, 18 Jun 2024 19:11:44 -0700 Subject: [PATCH] libmain: fix UB in verbosity assignment This was generating an out-of-range verbosity value. We should just process it as an int and then convert to verbosity with a clamping function, which trivially avoids any domain type violations. Change-Id: I0ed20da8e1496a1225ff3008b76827d99265d404 --- src/libmain/common-args.cc | 5 +++-- src/libutil/error.hh | 2 ++ src/libutil/logging.cc | 7 +++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libmain/common-args.cc b/src/libmain/common-args.cc index 20b5befe4..8fcb10325 100644 --- a/src/libmain/common-args.cc +++ b/src/libmain/common-args.cc @@ -1,5 +1,6 @@ #include "common-args.hh" #include "args/root.hh" +#include "error.hh" #include "globals.hh" #include "loggers.hh" #include "logging.hh" @@ -14,14 +15,14 @@ MixCommonArgs::MixCommonArgs(const std::string & programName) .shortName = 'v', .description = "Increase the logging verbosity level.", .category = loggingCategory, - .handler = {[]() { verbosity = (Verbosity) (verbosity + 1); }}, + .handler = {[]() { verbosity = verbosityFromIntClamped(int(verbosity) + 1); }}, }); addFlag({ .longName = "quiet", .description = "Decrease the logging verbosity level.", .category = loggingCategory, - .handler = {[]() { verbosity = verbosity > lvlError ? (Verbosity) (verbosity - 1) : lvlError; }}, + .handler = {[]() { verbosity = verbosityFromIntClamped(int(verbosity) - 1); }}, }); addFlag({ diff --git a/src/libutil/error.hh b/src/libutil/error.hh index 0884f9f32..06dfba0df 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -45,6 +45,8 @@ typedef enum { lvlVomit } Verbosity; +Verbosity verbosityFromIntClamped(int val); + /** * The lines of code surrounding an error. */ diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index b01bb4dd4..fecbc89ac 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -5,6 +5,7 @@ #include "position.hh" #include "terminal.hh" +#include #include #include #include @@ -110,6 +111,12 @@ public: Verbosity verbosity = lvlInfo; +Verbosity verbosityFromIntClamped(int val) +{ + int clamped = std::clamp(val, int(lvlError), int(lvlVomit)); + return static_cast(clamped); +} + void writeToStderr(std::string_view s) { try {