LibMedia: Don't store view into deleted ByteString

DecoderError::formatted() made a ByteString, took a view into it,
dropped the ByteString, then propagated the (now invalid) view back to
the caller as an error.
Since the object has to keep the ByteString alive, keep it as a variant
to make sure the "happy" path with no alloc remains alloc-free.
This commit is contained in:
Ali Mohammad Pur 2025-08-30 08:01:45 +02:00 committed by Jelle Raaijmakers
commit 8b3e888920
Notes: github-actions[bot] 2025-09-01 09:12:58 +00:00

View file

@ -34,7 +34,8 @@ enum class DecoderErrorCategory : u32 {
class DecoderError { class DecoderError {
public: public:
static DecoderError with_description(DecoderErrorCategory category, StringView description) template<OneOf<StringView, ByteString> T>
static DecoderError with_description(DecoderErrorCategory category, T description)
{ {
return DecoderError(category, description); return DecoderError(category, description);
} }
@ -62,25 +63,30 @@ public:
} }
DecoderErrorCategory category() const { return m_category; } DecoderErrorCategory category() const { return m_category; }
StringView description() const { return m_description; } StringView description() const
StringView string_literal() const { return m_description; } {
return m_description.visit([](StringView x) { return x; }, [](ByteString const& x) { return x.view(); });
}
// For compatibility with AK::Error
StringView string_literal() const { return description(); }
private: private:
DecoderError(DecoderErrorCategory category, ByteString description) template<OneOf<StringView, ByteString> T>
DecoderError(DecoderErrorCategory category, T description)
: m_category(category) : m_category(category)
, m_description(move(description)) , m_description(move(description))
{ {
} }
DecoderErrorCategory m_category { DecoderErrorCategory::Unknown }; DecoderErrorCategory m_category { DecoderErrorCategory::Unknown };
ByteString m_description; Variant<StringView, ByteString> m_description;
}; };
#define DECODER_TRY(category, expression) \ #define DECODER_TRY(category, expression) \
({ \ ({ \
auto&& _result = ((expression)); \ auto&& _result = ((expression)); \
if (_result.is_error()) [[unlikely]] { \ if (_result.is_error()) [[unlikely]] { \
auto _error_string = _result.release_error().string_literal(); \ auto _error_string = _result.error().string_literal(); \
return DecoderError::from_source_location( \ return DecoderError::from_source_location( \
((category)), _error_string, SourceLocation::current()); \ ((category)), _error_string, SourceLocation::current()); \
} \ } \