summaryrefslogtreecommitdiff
path: root/Tests/AK
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-08-28 11:19:21 -0400
committerLinus Groh <mail@linusgroh.de>2021-08-30 19:42:40 +0100
commit587d4663a339200a82b518d74c9400f4b77c8380 (patch)
tree89b573b4810cf478036247e46065b60f75e051c3 /Tests/AK
parentaa2e19e58f51ff2b6648809fc6a4d4ce1dc9df48 (diff)
downloadserenity-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.txt1
-rw-r--r--Tests/AK/TestStdLibExtras.cpp56
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>());
+}