diff options
author | Timothy Flynn <trflynn89@pm.me> | 2021-08-28 11:19:21 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-08-30 19:42:40 +0100 |
commit | 587d4663a339200a82b518d74c9400f4b77c8380 (patch) | |
tree | 89b573b4810cf478036247e46065b60f75e051c3 /Tests/AK | |
parent | aa2e19e58f51ff2b6648809fc6a4d4ce1dc9df48 (diff) | |
download | serenity-587d4663a339200a82b518d74c9400f4b77c8380.zip |
AK: Return early from swap() when swapping the same object
When swapping the same object, we could end up with a double-free error.
This was found while quick-sorting a Vector of Variants holding complex
types, reproduced by the new swap_same_complex_object test case.
Diffstat (limited to 'Tests/AK')
-rw-r--r-- | Tests/AK/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Tests/AK/TestStdLibExtras.cpp | 56 |
2 files changed, 57 insertions, 0 deletions
diff --git a/Tests/AK/CMakeLists.txt b/Tests/AK/CMakeLists.txt index 61cb63a14e..ba5f1fb7c0 100644 --- a/Tests/AK/CMakeLists.txt +++ b/Tests/AK/CMakeLists.txt @@ -51,6 +51,7 @@ set(AK_TEST_SOURCES TestSourceLocation.cpp TestSpan.cpp TestStack.cpp + TestStdLibExtras.cpp TestString.cpp TestStringUtils.cpp TestStringView.cpp diff --git a/Tests/AK/TestStdLibExtras.cpp b/Tests/AK/TestStdLibExtras.cpp new file mode 100644 index 0000000000..6a371cfcac --- /dev/null +++ b/Tests/AK/TestStdLibExtras.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, Tim Flynn <trflynn89@pm.me> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibTest/TestSuite.h> + +#include <AK/Optional.h> +#include <AK/StdLibExtras.h> +#include <AK/StringView.h> +#include <AK/Variant.h> +#include <AK/Vector.h> + +TEST_CASE(swap) +{ + int i = 4; + int j = 6; + + swap(i, j); + + EXPECT_EQ(i, 6); + EXPECT_EQ(j, 4); +} + +TEST_CASE(swap_same_value) +{ + + int i = 4; + swap(i, i); + EXPECT_EQ(i, 4); +} + +TEST_CASE(swap_same_complex_object) +{ + struct Type1 { + StringView foo; + }; + struct Type2 { + Optional<Type1> foo; + Vector<Type1> bar; + }; + + Variant<Type1, Type2> value1 { Type1 { "hello"sv } }; + Variant<Type1, Type2> value2 { Type2 { {}, { { "goodbye"sv } } } }; + + swap(value1, value2); + + EXPECT(value1.has<Type2>()); + EXPECT(value2.has<Type1>()); + + swap(value1, value1); + + EXPECT(value1.has<Type2>()); + EXPECT(value2.has<Type1>()); +} |