From f502e24bd72efe332d39ac0c337507bfea1f6684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Sun, 11 Dec 2022 14:32:56 +0100 Subject: [PATCH] AK: Change the moved-from String state to the empty short string The previous moved-from state was the null string. This violates both our invariant that String is never null, and also the C++ contract that the moved-from state must be valid but unspecified. The empty short string state is of course valid, so it satisfies both invariants. It also allows us to remove any extra checks for the null state. The reason this change is made is primarily because swap() requires moved-from objects to be reassignable (C++ allows this). Because the move assignment of String would not check the null state, it crashed trying to increment the data reference count (nullptr signals a non-short string). This meant that e.g. quick_sort'ing String would crash immediately. --- AK/String.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AK/String.cpp b/AK/String.cpp index c92c3c54eb..8c9afb0aee 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -177,6 +177,7 @@ String::String(String const& other) String::String(String&& other) : m_data(exchange(other.m_data, nullptr)) { + other.m_short_string.byte_count_and_short_string_flag = SHORT_STRING_FLAG; } String& String::operator=(String&& other) @@ -185,6 +186,7 @@ String& String::operator=(String&& other) m_data->unref(); m_data = exchange(other.m_data, nullptr); + other.m_short_string.byte_count_and_short_string_flag = SHORT_STRING_FLAG; return *this; } @@ -200,7 +202,7 @@ String& String::operator=(String const& other) String::~String() { - if (!is_short_string() && m_data) + if (!is_short_string()) m_data->unref(); }