From 74e8aa73e5a5c3156299c581c02aae563edb2388 Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Sun, 31 Oct 2021 17:11:58 -0600 Subject: [PATCH] AK: Avoid implicit conversions in TypeErasedParameter::to_size() Refactor to a visitor+functor pattern that does an explicit static_cast to size_t after performing suitable range checks for each type. --- AK/Format.h | 56 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/AK/Format.h b/AK/Format.h index cd23a6e577..092088284d 100644 --- a/AK/Format.h +++ b/AK/Format.h @@ -85,32 +85,40 @@ struct TypeErasedParameter { return Type::Custom; } + template + constexpr auto visit(Visitor&& visitor) const + { + switch (type) { + case TypeErasedParameter::Type::UInt8: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::UInt16: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::UInt32: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::UInt64: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::Int8: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::Int16: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::Int32: + return visitor(*static_cast(value)); + case TypeErasedParameter::Type::Int64: + return visitor(*static_cast(value)); + default: + TODO(); + } + } + constexpr size_t to_size() const { - i64 svalue; - - if (type == TypeErasedParameter::Type::UInt8) - svalue = *static_cast(value); - else if (type == TypeErasedParameter::Type::UInt16) - svalue = *static_cast(value); - else if (type == TypeErasedParameter::Type::UInt32) - svalue = *static_cast(value); - else if (type == TypeErasedParameter::Type::UInt64) - svalue = *static_cast(value); - else if (type == TypeErasedParameter::Type::Int8) - svalue = *static_cast(value); - else if (type == TypeErasedParameter::Type::Int16) - svalue = *static_cast(value); - else if (type == TypeErasedParameter::Type::Int32) - svalue = *static_cast(value); - else if (type == TypeErasedParameter::Type::Int64) - svalue = *static_cast(value); - else - VERIFY_NOT_REACHED(); - - VERIFY(svalue >= 0); - - return static_cast(svalue); + return visit([](T value) { + if constexpr (sizeof(T) > sizeof(size_t)) + VERIFY(value < NumericLimits::max()); + if constexpr (IsSigned) + VERIFY(value > 0); + return static_cast(value); + }); } // FIXME: Getters and setters.