3 Commits 6bb0d585e3 ... a5df972055

Tác giả SHA1 Thông báo Ngày
  Shannon Booth a5df972055 LibWeb: Do not store network errors as a StringView 1 tuần trước cách đây
  Kenneth Myhra 82a2ae99c8 Everywhere: Remove DeprecatedFlyString + any remaining references to it 1 tuần trước cách đây
  Ali Mohammad Pur 4136d8d13e LibRegex: Use an interned string table for capture group names 1 tuần trước cách đây

+ 3 - 8
AK/ByteString.cpp

@@ -6,7 +6,7 @@
 
 #include <AK/ByteBuffer.h>
 #include <AK/ByteString.h>
-#include <AK/DeprecatedFlyString.h>
+#include <AK/FlyString.h>
 #include <AK/Format.h>
 #include <AK/Function.h>
 #include <AK/StdLibExtras.h>
@@ -16,11 +16,6 @@
 
 namespace AK {
 
-bool ByteString::operator==(DeprecatedFlyString const& fly_string) const
-{
-    return m_impl == fly_string.impl() || view() == fly_string.view();
-}
-
 bool ByteString::operator==(ByteString const& other) const
 {
     return m_impl == other.impl() || view() == other.view();
@@ -337,8 +332,8 @@ ByteString escape_html_entities(StringView html)
     return builder.to_byte_string();
 }
 
-ByteString::ByteString(DeprecatedFlyString const& string)
-    : m_impl(string.impl())
+ByteString::ByteString(FlyString const& string)
+    : m_impl(*StringImpl::create(string.bytes()))
 {
 }
 

+ 1 - 3
AK/ByteString.h

@@ -86,7 +86,7 @@ public:
     {
     }
 
-    ByteString(DeprecatedFlyString const&);
+    ByteString(FlyString const&);
 
     static ErrorOr<ByteString> from_utf8(ReadonlyBytes);
     static ErrorOr<ByteString> from_utf8(StringView string) { return from_utf8(string.bytes()); }
@@ -228,8 +228,6 @@ public:
 
     bool operator==(StringView) const;
 
-    bool operator==(DeprecatedFlyString const&) const;
-
     bool operator<(ByteString const&) const;
     bool operator>=(ByteString const& other) const { return !(*this < other); }
     bool operator>=(char const* other) const { return !(*this < other); }

+ 0 - 1
AK/CMakeLists.txt

@@ -5,7 +5,6 @@ set(SOURCES
     ConstrainedStream.cpp
     CountingStream.cpp
     DOSPackedTime.cpp
-    DeprecatedFlyString.cpp
     ByteString.cpp
     Error.cpp
     FloatingPointStringConversions.cpp

+ 0 - 108
AK/DeprecatedFlyString.cpp

@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <AK/ByteString.h>
-#include <AK/DeprecatedFlyString.h>
-#include <AK/HashTable.h>
-#include <AK/Optional.h>
-#include <AK/Singleton.h>
-#include <AK/StringUtils.h>
-#include <AK/StringView.h>
-
-namespace AK {
-
-struct DeprecatedFlyStringImplTraits : public Traits<StringImpl const*> {
-    static unsigned hash(StringImpl const* s) { return s->hash(); }
-    static bool equals(StringImpl const* a, StringImpl const* b)
-    {
-        return *a == *b;
-    }
-};
-
-static Singleton<HashTable<StringImpl const*, DeprecatedFlyStringImplTraits>> s_table;
-
-static HashTable<StringImpl const*, DeprecatedFlyStringImplTraits>& fly_impls()
-{
-    return *s_table;
-}
-
-void DeprecatedFlyString::did_destroy_impl(Badge<StringImpl>, StringImpl& impl)
-{
-    fly_impls().remove(&impl);
-}
-
-DeprecatedFlyString::DeprecatedFlyString(ByteString const& string)
-    : m_impl(string.impl())
-{
-    if (string.impl()->is_fly())
-        return;
-
-    auto it = fly_impls().find(string.impl());
-    if (it == fly_impls().end()) {
-        fly_impls().set(string.impl());
-        string.impl()->set_fly({}, true);
-        m_impl = string.impl();
-    } else {
-        VERIFY((*it)->is_fly());
-        m_impl = **it;
-    }
-}
-
-DeprecatedFlyString::DeprecatedFlyString(StringView string)
-    : m_impl(StringImpl::the_empty_stringimpl())
-{
-    if (string.is_null())
-        return;
-    auto it = fly_impls().find(string.hash(), [&](auto& candidate) {
-        return string == *candidate;
-    });
-    if (it == fly_impls().end()) {
-        auto new_string = string.to_byte_string();
-        fly_impls().set(new_string.impl());
-        new_string.impl()->set_fly({}, true);
-        m_impl = new_string.impl();
-    } else {
-        VERIFY((*it)->is_fly());
-        m_impl = **it;
-    }
-}
-
-bool DeprecatedFlyString::equals_ignoring_ascii_case(StringView other) const
-{
-    return StringUtils::equals_ignoring_ascii_case(view(), other);
-}
-
-bool DeprecatedFlyString::starts_with(StringView str, CaseSensitivity case_sensitivity) const
-{
-    return StringUtils::starts_with(view(), str, case_sensitivity);
-}
-
-bool DeprecatedFlyString::ends_with(StringView str, CaseSensitivity case_sensitivity) const
-{
-    return StringUtils::ends_with(view(), str, case_sensitivity);
-}
-
-DeprecatedFlyString DeprecatedFlyString::to_lowercase() const
-{
-    return ByteString(*m_impl).to_lowercase();
-}
-
-bool DeprecatedFlyString::operator==(ByteString const& other) const
-{
-    return m_impl == other.impl() || view() == other.view();
-}
-
-bool DeprecatedFlyString::operator==(StringView string) const
-{
-    return view() == string;
-}
-
-bool DeprecatedFlyString::operator==(char const* string) const
-{
-    return view() == string;
-}
-
-}

+ 0 - 105
AK/DeprecatedFlyString.h

@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <AK/ByteString.h>
-#include <AK/StringUtils.h>
-
-namespace AK {
-
-class DeprecatedFlyString {
-public:
-    DeprecatedFlyString()
-        : m_impl(StringImpl::the_empty_stringimpl())
-    {
-    }
-    DeprecatedFlyString(DeprecatedFlyString const& other)
-        : m_impl(other.impl())
-    {
-    }
-    DeprecatedFlyString(DeprecatedFlyString&& other)
-        : m_impl(move(other.m_impl))
-    {
-    }
-    DeprecatedFlyString(ByteString const&);
-    DeprecatedFlyString(StringView);
-    DeprecatedFlyString(char const* string)
-        : DeprecatedFlyString(static_cast<ByteString>(string))
-    {
-    }
-
-    static DeprecatedFlyString from_fly_impl(NonnullRefPtr<StringImpl const> impl)
-    {
-        VERIFY(impl->is_fly());
-        DeprecatedFlyString string;
-        string.m_impl = move(impl);
-        return string;
-    }
-
-    DeprecatedFlyString& operator=(DeprecatedFlyString const& other)
-    {
-        m_impl = other.m_impl;
-        return *this;
-    }
-
-    DeprecatedFlyString& operator=(DeprecatedFlyString&& other)
-    {
-        m_impl = move(other.m_impl);
-        return *this;
-    }
-
-    bool is_empty() const { return !m_impl->length(); }
-
-    bool operator==(DeprecatedFlyString const& other) const { return m_impl == other.m_impl; }
-
-    bool operator==(ByteString const&) const;
-
-    bool operator==(StringView) const;
-
-    bool operator==(char const*) const;
-
-    NonnullRefPtr<StringImpl const> impl() const { return m_impl; }
-    char const* characters() const { return m_impl->characters(); }
-    size_t length() const { return m_impl->length(); }
-
-    ALWAYS_INLINE u32 hash() const { return m_impl->existing_hash(); }
-    ALWAYS_INLINE StringView view() const { return m_impl->view(); }
-
-    DeprecatedFlyString to_lowercase() const;
-
-    template<Arithmetic T>
-    Optional<T> to_number(TrimWhitespace trim_whitespace = TrimWhitespace::Yes) const
-    {
-        return view().to_number<T>(trim_whitespace);
-    }
-
-    bool equals_ignoring_ascii_case(StringView) const;
-    bool starts_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
-    bool ends_with(StringView, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
-
-    static void did_destroy_impl(Badge<StringImpl>, StringImpl&);
-
-    template<typename... Ts>
-    [[nodiscard]] ALWAYS_INLINE constexpr bool is_one_of(Ts&&... strings) const
-    {
-        return (... || this->operator==(forward<Ts>(strings)));
-    }
-
-private:
-    NonnullRefPtr<StringImpl const> m_impl;
-};
-
-template<>
-struct Traits<DeprecatedFlyString> : public DefaultTraits<DeprecatedFlyString> {
-    static unsigned hash(DeprecatedFlyString const& s) { return s.hash(); }
-};
-
-}
-
-#if USING_AK_GLOBALLY
-using AK::DeprecatedFlyString;
-#endif

+ 1 - 1
AK/Error.h

@@ -40,7 +40,7 @@ public:
     }
     static Error from_string_view(StringView string_literal) { return Error(string_literal); }
 
-    template<OneOf<ByteString, DeprecatedFlyString, String, FlyString> T>
+    template<OneOf<ByteString, String, FlyString> T>
     static Error from_string_view(T)
     {
         // `Error::from_string_view(ByteString::formatted(...))` is a somewhat common mistake, which leads to a UAF situation.

+ 0 - 11
AK/FlyString.cpp

@@ -4,7 +4,6 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
-#include <AK/DeprecatedFlyString.h>
 #include <AK/FlyString.h>
 #include <AK/HashTable.h>
 #include <AK/Singleton.h>
@@ -120,16 +119,6 @@ size_t FlyString::number_of_fly_strings()
     return all_fly_strings().size();
 }
 
-DeprecatedFlyString FlyString::to_deprecated_fly_string() const
-{
-    return DeprecatedFlyString(bytes_as_string_view());
-}
-
-ErrorOr<FlyString> FlyString::from_deprecated_fly_string(DeprecatedFlyString const& deprecated_fly_string)
-{
-    return FlyString::from_utf8(deprecated_fly_string.view());
-}
-
 unsigned Traits<FlyString>::hash(FlyString const& fly_string)
 {
     return fly_string.hash();

+ 1 - 4
AK/FlyString.h

@@ -26,7 +26,7 @@ public:
     static ErrorOr<FlyString> from_utf8(StringView);
     static FlyString from_utf8_without_validation(ReadonlyBytes);
     template<typename T>
-    requires(IsOneOf<RemoveCVReference<T>, ByteString, DeprecatedFlyString, FlyString, String>)
+    requires(IsOneOf<RemoveCVReference<T>, ByteString, FlyString, String>)
     static ErrorOr<String> from_utf8(T&&) = delete;
 
     FlyString(String const&);
@@ -55,9 +55,6 @@ public:
     // This is primarily interesting to unit tests.
     [[nodiscard]] static size_t number_of_fly_strings();
 
-    // FIXME: Remove these once all code has been ported to FlyString
-    [[nodiscard]] DeprecatedFlyString to_deprecated_fly_string() const;
-    static ErrorOr<FlyString> from_deprecated_fly_string(DeprecatedFlyString const&);
     template<typename T>
     requires(IsSame<RemoveCVReference<T>, StringView>)
     static ErrorOr<String> from_deprecated_fly_string(T&&) = delete;

+ 0 - 3
AK/Format.h

@@ -496,9 +496,6 @@ struct Formatter<unsigned char[Size]> : Formatter<StringView> {
 template<>
 struct Formatter<ByteString> : Formatter<StringView> {
 };
-template<>
-struct Formatter<DeprecatedFlyString> : Formatter<StringView> {
-};
 
 template<typename T>
 struct Formatter<T*> : StandardFormatter {

+ 0 - 2
AK/Forward.h

@@ -29,7 +29,6 @@ using ByteBuffer = Detail::ByteBuffer<32>;
 class CircularBuffer;
 class ConstrainedStream;
 class CountingStream;
-class DeprecatedFlyString;
 class ByteString;
 class Duration;
 class Error;
@@ -161,7 +160,6 @@ using AK::CircularBuffer;
 using AK::CircularQueue;
 using AK::ConstrainedStream;
 using AK::CountingStream;
-using AK::DeprecatedFlyString;
 using AK::DoublyLinkedList;
 using AK::Error;
 using AK::ErrorOr;

+ 1 - 1
AK/String.h

@@ -60,7 +60,7 @@ public:
     [[nodiscard]] static String from_utf8_with_replacement_character(StringView, WithBOMHandling = WithBOMHandling::Yes);
 
     template<typename T>
-    requires(IsOneOf<RemoveCVReference<T>, ByteString, DeprecatedFlyString, FlyString, String>)
+    requires(IsOneOf<RemoveCVReference<T>, ByteString, FlyString, String>)
     static ErrorOr<String> from_utf8(T&&) = delete;
 
     [[nodiscard]] static String from_utf8_without_validation(ReadonlyBytes);

+ 1 - 6
AK/StringImpl.cpp

@@ -5,7 +5,6 @@
  */
 
 #include <AK/CharacterTypes.h>
-#include <AK/DeprecatedFlyString.h>
 #include <AK/StringHash.h>
 #include <AK/StringImpl.h>
 #include <AK/kmalloc.h>
@@ -28,11 +27,7 @@ StringImpl::StringImpl(ConstructWithInlineBufferTag, size_t length)
 {
 }
 
-StringImpl::~StringImpl()
-{
-    if (m_fly)
-        DeprecatedFlyString::did_destroy_impl({}, *this);
-}
+StringImpl::~StringImpl() = default;
 
 NonnullRefPtr<StringImpl const> StringImpl::create_uninitialized(size_t length, char*& buffer)
 {

+ 0 - 3
AK/StringImpl.h

@@ -77,9 +77,6 @@ public:
 
     unsigned case_insensitive_hash() const;
 
-    bool is_fly() const { return m_fly; }
-    void set_fly(Badge<DeprecatedFlyString>, bool fly) const { m_fly = fly; }
-
 private:
     enum ConstructTheEmptyStringImplTag {
         ConstructTheEmptyStringImpl

+ 0 - 7
AK/StringView.cpp

@@ -7,7 +7,6 @@
 #include <AK/AnyOf.h>
 #include <AK/ByteBuffer.h>
 #include <AK/ByteString.h>
-#include <AK/DeprecatedFlyString.h>
 #include <AK/Find.h>
 #include <AK/FlyString.h>
 #include <AK/Function.h>
@@ -36,12 +35,6 @@ StringView::StringView(ByteString const& string)
 {
 }
 
-StringView::StringView(DeprecatedFlyString const& string)
-    : m_characters(string.characters())
-    , m_length(string.length())
-{
-}
-
 StringView::StringView(ByteBuffer const& buffer)
     : m_characters((char const*)buffer.data())
     , m_length(buffer.size())

+ 1 - 3
AK/StringView.h

@@ -51,15 +51,13 @@ public:
     StringView(String const&);
     StringView(FlyString const&);
     StringView(ByteString const&);
-    StringView(DeprecatedFlyString const&);
 
     explicit StringView(ByteBuffer&&) = delete;
     explicit StringView(String&&) = delete;
     explicit StringView(FlyString&&) = delete;
     explicit StringView(ByteString&&) = delete;
-    explicit StringView(DeprecatedFlyString&&) = delete;
 
-    template<OneOf<String, FlyString, ByteString, DeprecatedFlyString, ByteBuffer> StringType>
+    template<OneOf<String, FlyString, ByteString, ByteBuffer> StringType>
     StringView& operator=(StringType&&) = delete;
 
     [[nodiscard]] constexpr bool is_null() const

+ 1 - 1
Libraries/LibJS/Runtime/VM.cpp

@@ -659,7 +659,7 @@ void VM::load_imported_module(ImportedModuleReferrer referrer, ModuleRequest con
         });
 
     LexicalPath base_path { base_filename };
-    auto filename = LexicalPath::absolute_path(base_path.dirname(), module_request.module_specifier.to_deprecated_fly_string());
+    auto filename = LexicalPath::absolute_path(base_path.dirname(), module_request.module_specifier);
 
     dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] base path: '{}'", base_path);
     dbgln_if(JS_MODULE_DEBUG, "[JS MODULE] initial filename: '{}'", filename);

+ 1 - 0
Libraries/LibRegex/RegexByteCode.cpp

@@ -161,6 +161,7 @@ static bool restore_string_position(MatchInput const& input, MatchState& state)
 OwnPtr<OpCode> ByteCode::s_opcodes[(size_t)OpCodeId::Last + 1];
 bool ByteCode::s_opcodes_initialized { false };
 size_t ByteCode::s_next_checkpoint_serial_id { 0 };
+u32 StringTable::next_serial { 0 };
 
 void ByteCode::ensure_opcodes_initialized()
 {

+ 88 - 11
Libraries/LibRegex/RegexByteCode.h

@@ -12,6 +12,7 @@
 #include <AK/Concepts.h>
 #include <AK/DisjointChunks.h>
 #include <AK/Forward.h>
+#include <AK/HashMap.h>
 #include <AK/OwnPtr.h>
 #include <AK/TypeCasts.h>
 #include <AK/Types.h>
@@ -141,6 +142,50 @@ struct CompareTypeAndValuePair {
 
 class OpCode;
 
+struct StringTable {
+    StringTable()
+        : m_serial(next_serial++)
+    {
+    }
+    StringTable(StringTable const&) = default;
+    StringTable(StringTable&&) = default;
+
+    ~StringTable()
+    {
+        if (m_serial == next_serial - 1 && m_table.is_empty())
+            --next_serial; // We didn't use this serial, put it back.
+    }
+
+    StringTable& operator=(StringTable const&) = default;
+    StringTable& operator=(StringTable&&) = default;
+
+    ByteCodeValueType set(FlyString string)
+    {
+        u32 local_index = m_table.size() + 0x4242;
+        ByteCodeValueType global_index;
+        if (auto maybe_local_index = m_table.get(string); maybe_local_index.has_value()) {
+            local_index = maybe_local_index.value();
+            global_index = static_cast<ByteCodeValueType>(m_serial) << 32 | static_cast<ByteCodeValueType>(local_index);
+        } else {
+            global_index = static_cast<ByteCodeValueType>(m_serial) << 32 | static_cast<ByteCodeValueType>(local_index);
+            m_table.set(string, global_index);
+            m_inverse_table.set(global_index, string);
+        }
+
+        return global_index;
+    }
+
+    FlyString get(ByteCodeValueType index) const
+    {
+        return m_inverse_table.get(index).value();
+    }
+
+    static u32 next_serial;
+    u32 m_serial { 0 };
+    HashMap<FlyString, ByteCodeValueType> m_table;
+    HashMap<ByteCodeValueType, FlyString> m_inverse_table;
+};
+
 class ByteCode : public DisjointChunks<ByteCodeValueType> {
     using Base = DisjointChunks<ByteCodeValueType>;
 
@@ -153,14 +198,27 @@ public:
     ByteCode(ByteCode const&) = default;
     ByteCode(ByteCode&&) = default;
 
+    ByteCode(Base&&) = delete;
+    ByteCode(Base const&) = delete;
+
     virtual ~ByteCode() = default;
 
     ByteCode& operator=(ByteCode const&) = default;
     ByteCode& operator=(ByteCode&&) = default;
-    ByteCode& operator=(Base&& value)
+
+    ByteCode& operator=(Base&& value) = delete;
+    ByteCode& operator=(Base const& value) = delete;
+
+    void extend(ByteCode&& other)
+    {
+        merge_string_tables_from({ &other, 1 });
+        Base::extend(move(other));
+    }
+
+    void extend(ByteCode const& other)
     {
-        static_cast<Base&>(*this) = move(value);
-        return *this;
+        merge_string_tables_from({ &other, 1 });
+        Base::extend(other);
     }
 
     template<typename... Args>
@@ -202,9 +260,28 @@ public:
         Base::last_chunk().ensure_capacity(capacity);
     }
 
+    FlyString get_string(size_t index) const { return m_string_table.get(index); }
+
     void last_chunk() const = delete;
     void first_chunk() const = delete;
 
+    void merge_string_tables_from(Span<ByteCode const> others)
+    {
+        for (auto const& other : others) {
+            for (auto const& entry : other.m_string_table.m_table) {
+                auto const result = m_string_table.m_inverse_table.set(entry.value, entry.key);
+                if (result != HashSetResult::InsertedNewEntry) {
+                    if (m_string_table.m_inverse_table.get(entry.value) == entry.key) // Already in inverse table.
+                        continue;
+                    dbgln("StringTable: Detected ID clash in string tables! ID {} seems to be reused", entry.value);
+                    dbgln("Old: {}, New: {}", m_string_table.m_inverse_table.get(entry.value), entry.key);
+                    VERIFY_NOT_REACHED();
+                }
+                m_string_table.m_table.set(entry.key, entry.value);
+            }
+        }
+    }
+
     void insert_bytecode_compare_values(Vector<CompareTypeAndValuePair>&& pairs)
     {
         Optimizer::append_character_class(*this, move(pairs));
@@ -246,11 +323,10 @@ public:
         empend(capture_groups_count);
     }
 
-    void insert_bytecode_group_capture_right(size_t capture_groups_count, StringView name)
+    void insert_bytecode_group_capture_right(size_t capture_groups_count, FlyString name)
     {
         empend(static_cast<ByteCodeValueType>(OpCodeId::SaveRightNamedCaptureGroup));
-        empend(reinterpret_cast<ByteCodeValueType>(name.characters_without_null_termination()));
-        empend(name.length());
+        empend(m_string_table.set(move(name)));
         empend(capture_groups_count);
     }
 
@@ -541,6 +617,7 @@ private:
     static OwnPtr<OpCode> s_opcodes[(size_t)OpCodeId::Last + 1];
     static bool s_opcodes_initialized;
     static size_t s_next_checkpoint_serial_id;
+    StringTable m_string_table;
 };
 
 #define ENUMERATE_EXECUTION_RESULTS                          \
@@ -758,13 +835,13 @@ class OpCode_SaveRightNamedCaptureGroup final : public OpCode {
 public:
     ExecutionResult execute(MatchInput const& input, MatchState& state) const override;
     ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::SaveRightNamedCaptureGroup; }
-    ALWAYS_INLINE size_t size() const override { return 4; }
-    ALWAYS_INLINE StringView name() const { return { reinterpret_cast<char*>(argument(0)), length() }; }
-    ALWAYS_INLINE size_t length() const { return argument(1); }
-    ALWAYS_INLINE size_t id() const { return argument(2); }
+    ALWAYS_INLINE size_t size() const override { return 3; }
+    ALWAYS_INLINE FlyString name() const { return m_bytecode->get_string(argument(0)); }
+    ALWAYS_INLINE size_t length() const { return name().bytes_as_string_view().length(); }
+    ALWAYS_INLINE size_t id() const { return argument(1); }
     ByteString arguments_string() const override
     {
-        return ByteString::formatted("name={}, length={}", name(), length());
+        return ByteString::formatted("name_id={}, id={}", argument(0), id());
     }
 };
 

+ 1 - 1
Libraries/LibRegex/RegexDebug.h

@@ -26,7 +26,7 @@ public:
         auto& bytecode = regex.parser_result.bytecode;
         size_t index { 0 };
         for (auto& value : bytecode) {
-            outln(m_file, "OpCode i={:3} [{:#02X}]", index, (u32)value);
+            outln(m_file, "OpCode i={:3} [{:#02X}]", index, value);
             ++index;
         }
     }

+ 2 - 0
Libraries/LibRegex/RegexOptimizer.cpp

@@ -999,6 +999,8 @@ void Optimizer::append_alternation(ByteCode& target, Span<ByteCode> alternatives
     if (alternatives.size() == 0)
         return;
 
+    target.merge_string_tables_from(alternatives);
+
     if (alternatives.size() == 1)
         return target.extend(move(alternatives[0]));
 

+ 6 - 7
Libraries/LibRegex/RegexParser.cpp

@@ -11,7 +11,6 @@
 #include <AK/ByteString.h>
 #include <AK/CharacterTypes.h>
 #include <AK/Debug.h>
-#include <AK/DeprecatedFlyString.h>
 #include <AK/GenericLexer.h>
 #include <AK/ScopeGuard.h>
 #include <AK/StringBuilder.h>
@@ -813,7 +812,7 @@ ALWAYS_INLINE bool PosixExtendedParser::parse_sub_expression(ByteCode& stack, si
                 NegativeLookbehind,
             } group_mode { Normal };
             consume();
-            Optional<StringView> capture_group_name;
+            Optional<FlyString> capture_group_name;
             bool prevent_capture_group = false;
             if (match(TokenType::Questionmark)) {
                 consume();
@@ -836,7 +835,7 @@ ALWAYS_INLINE bool PosixExtendedParser::parse_sub_expression(ByteCode& stack, si
                         ++capture_group_name_length;
                         last_token = consume();
                     }
-                    capture_group_name = StringView(start_token.value().characters_without_null_termination(), capture_group_name_length);
+                    capture_group_name = MUST(FlyString::from_utf8(m_parser_state.lexer.input().substring_view_starting_from_substring(start_token.value()).substring_view(0, capture_group_name_length)));
                     ++m_parser_state.named_capture_groups_count;
 
                 } else if (match(TokenType::EqualSign)) { // positive lookahead
@@ -982,7 +981,7 @@ bool ECMA262Parser::parse_pattern(ByteCode& stack, size_t& match_length_minimum,
     return parse_disjunction(stack, match_length_minimum, flags);
 }
 
-bool ECMA262Parser::has_duplicate_in_current_alternative(DeprecatedFlyString const& name)
+bool ECMA262Parser::has_duplicate_in_current_alternative(FlyString const& name)
 {
     auto it = m_parser_state.named_capture_groups.find(name);
     if (it == m_parser_state.named_capture_groups.end())
@@ -2503,7 +2502,7 @@ bool ECMA262Parser::parse_unicode_property_escape(PropertyEscape& property, bool
         [](Empty&) -> bool { VERIFY_NOT_REACHED(); });
 }
 
-DeprecatedFlyString ECMA262Parser::read_capture_group_specifier(bool take_starting_angle_bracket)
+FlyString ECMA262Parser::read_capture_group_specifier(bool take_starting_angle_bracket)
 {
     static constexpr u32 const REPLACEMENT_CHARACTER = 0xFFFD;
     constexpr u32 const ZERO_WIDTH_NON_JOINER { 0x200C };
@@ -2604,7 +2603,7 @@ DeprecatedFlyString ECMA262Parser::read_capture_group_specifier(bool take_starti
         builder.append_code_point(code_point);
     }
 
-    DeprecatedFlyString name = builder.to_byte_string();
+    auto name = MUST(builder.to_fly_string());
     if (!hit_end || name.is_empty())
         set_error(Error::InvalidNameForCaptureGroup);
 
@@ -2720,7 +2719,7 @@ bool ECMA262Parser::parse_capture_group(ByteCode& stack, size_t& match_length_mi
 
             stack.insert_bytecode_group_capture_left(group_index);
             stack.extend(move(capture_group_bytecode));
-            stack.insert_bytecode_group_capture_right(group_index, name.view());
+            stack.insert_bytecode_group_capture_right(group_index, name);
 
             match_length_minimum += length;
 

+ 5 - 5
Libraries/LibRegex/RegexParser.h

@@ -11,7 +11,7 @@
 #include "RegexLexer.h"
 #include "RegexOptions.h"
 
-#include <AK/DeprecatedFlyString.h>
+#include <AK/FlyString.h>
 #include <AK/Forward.h>
 #include <AK/HashMap.h>
 #include <AK/Types.h>
@@ -59,7 +59,7 @@ public:
         size_t match_length_minimum;
         Error error;
         Token error_token;
-        Vector<DeprecatedFlyString> capture_groups;
+        Vector<FlyString> capture_groups;
         AllOptions options;
 
         struct {
@@ -117,7 +117,7 @@ protected:
         size_t repetition_mark_count { 0 };
         AllOptions regex_options;
         HashMap<size_t, size_t> capture_group_minimum_lengths;
-        HashMap<DeprecatedFlyString, Vector<NamedCaptureGroup>> named_capture_groups;
+        HashMap<FlyString, Vector<NamedCaptureGroup>> named_capture_groups;
 
         explicit ParserState(Lexer& lexer)
             : lexer(lexer)
@@ -240,7 +240,7 @@ private:
     };
     StringView read_digits_as_string(ReadDigitsInitialZeroState initial_zero = ReadDigitsInitialZeroState::Allow, bool hex = false, int max_count = -1, int min_count = -1);
     Optional<unsigned> read_digits(ReadDigitsInitialZeroState initial_zero = ReadDigitsInitialZeroState::Allow, bool hex = false, int max_count = -1, int min_count = -1);
-    DeprecatedFlyString read_capture_group_specifier(bool take_starting_angle_bracket = false);
+    FlyString read_capture_group_specifier(bool take_starting_angle_bracket = false);
 
     struct Script {
         Unicode::Script script {};
@@ -282,7 +282,7 @@ private:
     bool parse_invalid_braced_quantifier(); // Note: This function either parses and *fails*, or doesn't parse anything and returns false.
     Optional<u8> parse_legacy_octal_escape();
 
-    bool has_duplicate_in_current_alternative(DeprecatedFlyString const& name);
+    bool has_duplicate_in_current_alternative(FlyString const& name);
 
     size_t ensure_total_number_of_capturing_parenthesis();
 

+ 1 - 1
Libraries/LibWeb/DOM/Document.cpp

@@ -2100,7 +2100,7 @@ WebIDL::ExceptionOr<GC::Ref<Element>> Document::create_element(String const& a_l
         namespace_ = Namespace::HTML;
 
     // 6. Return the result of creating an element given this, localName, namespace, null, is, and with the synchronous custom elements flag set.
-    return TRY(DOM::create_element(*this, MUST(FlyString::from_deprecated_fly_string(local_name)), move(namespace_), {}, move(is_value), true));
+    return TRY(DOM::create_element(*this, FlyString::from_utf8_without_validation(local_name.bytes()), move(namespace_), {}, move(is_value), true));
 }
 
 // https://dom.spec.whatwg.org/#dom-document-createelementns

+ 1 - 1
Libraries/LibWeb/DOM/Node.cpp

@@ -2206,7 +2206,7 @@ GC::Ref<Node> Node::get_root_node(GetRootNodeOptions const& options)
 String Node::debug_description() const
 {
     StringBuilder builder;
-    builder.append(node_name().to_deprecated_fly_string().to_lowercase());
+    builder.append(node_name().to_ascii_lowercase());
     if (is_element()) {
         auto const& element = static_cast<DOM::Element const&>(*this);
         if (element.id().has_value())

+ 1 - 1
Libraries/LibWeb/Fetch/FetchMethod.cpp

@@ -104,7 +104,7 @@ GC::Ref<WebIDL::Promise> fetch(JS::VM& vm, RequestInfo const& input, RequestInit
 
         // 3. If response is a network error, then reject p with a TypeError and abort these steps.
         if (response->is_network_error()) {
-            auto message = response->network_error_message().value_or("Response is a network error"sv);
+            auto message = response->network_error_message().value_or("Response is a network error"_string);
             WebIDL::reject_promise(relevant_realm, promise_capability, JS::TypeError::create(relevant_realm, message));
             return;
         }

+ 23 - 23
Libraries/LibWeb/Fetch/Fetching/Fetching.cpp

@@ -284,7 +284,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
     // 3. If request’s local-URLs-only flag is set and request’s current URL is not local, then set response to a
     //    network error.
     if (request->local_urls_only() && !Infrastructure::is_local_url(request->current_url()))
-        response = Infrastructure::Response::network_error(vm, "Request with 'local-URLs-only' flag must have a local URL"sv);
+        response = Infrastructure::Response::network_error(vm, "Request with 'local-URLs-only' flag must have a local URL"_string);
 
     // 4. Run report Content Security Policy violations for request.
     ContentSecurityPolicy::report_content_security_policy_violations_for_request(realm, request);
@@ -299,7 +299,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
     if (Infrastructure::block_bad_port(request) == Infrastructure::RequestOrResponseBlocking::Blocked
         || MixedContent::should_fetching_request_be_blocked_as_mixed_content(request) == Infrastructure::RequestOrResponseBlocking::Blocked
         || ContentSecurityPolicy::should_request_be_blocked_by_content_security_policy(realm, request) == ContentSecurityPolicy::Directives::Directive::Result::Blocked) {
-        response = Infrastructure::Response::network_error(vm, "Request was blocked"sv);
+        response = Infrastructure::Response::network_error(vm, "Request was blocked"_string);
     }
 
     // 8. If request’s referrer policy is the empty string, then set request’s referrer policy to request’s policy
@@ -374,13 +374,13 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
         // -> request’s mode is "same-origin"
         else if (request->mode() == Infrastructure::Request::Mode::SameOrigin) {
             // Return a network error.
-            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'same-origin' mode must have same URL and request origin"sv));
+            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'same-origin' mode must have same URL and request origin"_string));
         }
         // -> request’s mode is "no-cors"
         else if (request->mode() == Infrastructure::Request::Mode::NoCORS) {
             // 1. If request’s redirect mode is not "follow", then return a network error.
             if (request->redirect_mode() != Infrastructure::Request::RedirectMode::Follow)
-                return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'no-cors' mode must have redirect mode set to 'follow'"sv));
+                return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'no-cors' mode must have redirect mode set to 'follow'"_string));
 
             // 2. Set request’s response tainting to "opaque".
             request->set_response_tainting(Infrastructure::Request::ResponseTainting::Opaque);
@@ -394,7 +394,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
             VERIFY(request->mode() == Infrastructure::Request::Mode::CORS);
 
             // Return a network error.
-            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'cors' mode must have URL with HTTP or HTTPS scheme"sv));
+            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'cors' mode must have URL with HTTP or HTTPS scheme"_string));
         }
         // -> request’s use-CORS-preflight flag is set
         // -> request’s unsafe-request flag is set and either request’s method is not a CORS-safelisted method or
@@ -563,7 +563,7 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
                 // 1. Let processBodyError be this step: run fetch response handover given fetchParams and a network
                 //    error.
                 auto process_body_error = GC::create_function(vm.heap(), [&realm, &vm, &fetch_params](JS::Value) {
-                    fetch_response_handover(realm, fetch_params, Infrastructure::Response::network_error(vm, "Response body could not be processed"sv));
+                    fetch_response_handover(realm, fetch_params, Infrastructure::Response::network_error(vm, "Response body could not be processed"_string));
                 });
 
                 // 2. If response’s body is null, then run processBodyError and abort these steps.
@@ -842,7 +842,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
         if (request->method() != "GET"sv.bytes() || !blob_url_entry.has_value()) {
             // FIXME: Handle "blobURLEntry’s object is not a Blob object". It could be a MediaSource object, but we
             //        have not yet implemented the Media Source Extensions spec.
-            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request has an invalid 'blob:' URL"sv));
+            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request has an invalid 'blob:' URL"_string));
         }
 
         // 3. Let requestEnvironment be the result of determining the environment given request.
@@ -853,7 +853,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
 
         // 5. If isTopLevelNavigation is false and requestEnvironment is null, then return a network error.
         if (!is_top_level_navigation && !request_environment)
-            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request is missing fetch client"sv));
+            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request is missing fetch client"_string));
 
         // 6. Let navigationOrEnvironment be the string "navigation" if isTopLevelNavigation is true; otherwise, requestEnvironment.
         auto navigation_or_environment = [&]() -> Variant<FileAPI::NavigationEnvironment, GC::Ref<HTML::Environment>> {
@@ -868,7 +868,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
         // 8. If blob is not a Blob object, then return a network error.
         // FIXME: This should probably check for a MediaSource object as well, once we implement that.
         if (!blob_object.has_value())
-            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Failed to obtain a Blob object from 'blob:' URL"sv));
+            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Failed to obtain a Blob object from 'blob:' URL"_string));
         auto const blob = FileAPI::Blob::create(realm, blob_object->data, blob_object->type);
 
         // 9. Let response be a new response.
@@ -914,7 +914,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
 
             // 4. If rangeValue is failure, then return a network error.
             if (!maybe_range_value.has_value())
-                return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Failed to parse single range header value"sv));
+                return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Failed to parse single range header value"_string));
 
             // 5. Let (rangeStart, rangeEnd) be rangeValue.
             auto& [range_start, range_end] = maybe_range_value.value();
@@ -933,7 +933,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
             else {
                 // 1. If rangeStart is greater than or equal to fullLength, then return a network error.
                 if (*range_start >= full_length)
-                    return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "rangeStart is greater than or equal to fullLength"sv));
+                    return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "rangeStart is greater than or equal to fullLength"_string));
 
                 // 2. If rangeEnd is null or rangeEnd is greater than or equal to fullLength, then set rangeEnd to fullLength − 1.
                 if (!range_end.has_value() || *range_end >= full_length)
@@ -986,7 +986,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
 
         // 2. If dataURLStruct is failure, then return a network error.
         if (data_url_struct.is_error())
-            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Failed to process 'data:' URL"sv));
+            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Failed to process 'data:' URL"_string));
 
         // 3. Let mimeType be dataURLStruct’s MIME type, serialized.
         auto const& mime_type = data_url_struct.value().mime_type.serialized();
@@ -1010,7 +1010,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> scheme_fetch(JS::Realm& realm, Inf
         if (request->origin().has<URL::Origin>() && (request->origin().get<URL::Origin>().is_opaque() || request->origin().get<URL::Origin>().scheme() == "file"sv || request->origin().get<URL::Origin>().scheme() == "resource"sv))
             return TRY(nonstandard_resource_loader_file_or_http_network_fetch(realm, fetch_params));
         else
-            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'file:' or 'resource:' URL blocked"sv));
+            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'file:' or 'resource:' URL blocked"_string));
     }
     // -> HTTP(S) scheme
     else if (Infrastructure::is_http_or_https_scheme(request->current_url().scheme())) {
@@ -1090,7 +1090,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_fetch(JS::Realm& realm, Infra
                 // - request’s redirect mode is not "follow" and response’s URL list has more than one item.
                 || (request->redirect_mode() != Infrastructure::Request::RedirectMode::Follow && response->url_list().size() > 1)) {
                 // then return a network error.
-                return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Invalid request/response state combination"sv));
+                return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Invalid request/response state combination"_string));
             }
         }
     }
@@ -1269,17 +1269,17 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> http_redirect_fetch(JS::Realm& rea
 
     // 5. If locationURL is failure, then return a network error.
     if (location_url_or_error.is_error())
-        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request redirect URL is invalid"sv));
+        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request redirect URL is invalid"_string));
 
     auto location_url = location_url_or_error.release_value().release_value();
 
     // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network error.
     if (!Infrastructure::is_http_or_https_scheme(location_url.scheme()))
-        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request redirect URL must have HTTP or HTTPS scheme"sv));
+        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request redirect URL must have HTTP or HTTPS scheme"_string));
 
     // 7. If request’s redirect count is 20, then return a network error.
     if (request->redirect_count() == 20)
-        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request has reached maximum redirect count of 20"sv));
+        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request has reached maximum redirect count of 20"_string));
 
     // 8. Increase request’s redirect count by 1.
     request->set_redirect_count(request->redirect_count() + 1);
@@ -1290,20 +1290,20 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> http_redirect_fetch(JS::Realm& rea
         && location_url.includes_credentials()
         && request->origin().has<URL::Origin>()
         && !request->origin().get<URL::Origin>().is_same_origin(location_url.origin())) {
-        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'cors' mode and different URL and request origin must not include credentials in redirect URL"sv));
+        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'cors' mode and different URL and request origin must not include credentials in redirect URL"_string));
     }
 
     // 10. If request’s response tainting is "cors" and locationURL includes credentials, then return a network error.
     // NOTE: This catches a cross-origin resource redirecting to a same-origin URL.
     if (request->response_tainting() == Infrastructure::Request::ResponseTainting::CORS && location_url.includes_credentials())
-        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'cors' response tainting must not include credentials in redirect URL"sv));
+        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'cors' response tainting must not include credentials in redirect URL"_string));
 
     // 11. If internalResponse’s status is not 303, request’s body is non-null, and request’s body’s source is null, then
     //     return a network error.
     if (internal_response->status() != 303
         && !request->body().has<Empty>()
         && request->body().get<GC::Ref<Infrastructure::Body>>()->source().has<Empty>()) {
-        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request has body but no body source"sv));
+        return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request has body but no body source"_string));
     }
 
     // 12. If one of the following is true
@@ -1811,7 +1811,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Re
 
             // 5. If the sum of contentLength and inflightKeepaliveBytes is greater than 64 kibibytes, then return a network error.
             if ((content_length.value() + inflight_keep_alive_bytes) > keepalive_maximum_size)
-                return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Keepalive request exceeded maximum allowed size of 64 KiB"sv));
+                return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Keepalive request exceeded maximum allowed size of 64 KiB"_string));
 
             // NOTE: The above limit ensures that requests that are allowed to outlive the environment settings object
             //       and contain a body, have a bounded size and are not allowed to stay alive indefinitely.
@@ -2053,7 +2053,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> http_network_or_cache_fetch(JS::Re
     if (!response) {
         // 1. If httpRequest’s cache mode is "only-if-cached", then return a network error.
         if (http_request->cache_mode() == Infrastructure::Request::CacheMode::OnlyIfCached)
-            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'only-if-cached' cache mode doesn't have a cached response"sv));
+            return PendingResponse::create(vm, request, Infrastructure::Response::network_error(vm, "Request with 'only-if-cached' cache mode doesn't have a cached response"_string));
 
         // 2. Let forwardResponse be the result of running HTTP-network fetch given httpFetchParams, includeCredentials,
         //    and isNewConnectionFetch.
@@ -2598,7 +2598,7 @@ WebIDL::ExceptionOr<GC::Ref<PendingResponse>> cors_preflight_fetch(JS::Realm& re
             //    is "include" or methods does not contain `*`, then return a network error.
             if (!methods.contains_slow(request.method()) && !Infrastructure::is_cors_safelisted_method(request.method())) {
                 if (request.credentials_mode() == Infrastructure::Request::CredentialsMode::Include) {
-                    returned_pending_response->resolve(Infrastructure::Response::network_error(vm, TRY_OR_IGNORE(String::formatted("Non-CORS-safelisted method '{}' not found in the CORS-preflight response's Access-Control-Allow-Methods header (the header may be missing). '*' is not allowed as the main request includes credentials."sv, StringView { request.method() }))));
+                    returned_pending_response->resolve(Infrastructure::Response::network_error(vm, TRY_OR_IGNORE(String::formatted("Non-CORS-safelisted method '{}' not found in the CORS-preflight response's Access-Control-Allow-Methods header (the header may be missing). '*' is not allowed as the main request includes credentials."_string, StringView { request.method() }))));
                     return;
                 }
 

+ 4 - 10
Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp

@@ -47,14 +47,14 @@ GC::Ref<Response> Response::create(JS::VM& vm)
 
 GC::Ref<Response> Response::aborted_network_error(JS::VM& vm)
 {
-    auto response = network_error(vm, "Fetch has been aborted"sv);
+    auto response = network_error(vm, "Fetch has been aborted"_string);
     response->set_aborted(true);
     return response;
 }
 
-GC::Ref<Response> Response::network_error(JS::VM& vm, Variant<String, StringView> message)
+GC::Ref<Response> Response::network_error(JS::VM& vm, String message)
 {
-    dbgln_if(WEB_FETCH_DEBUG, "Fetch: Creating network error response with message: {}", message.visit([](auto const& s) -> StringView { return s; }));
+    dbgln_if(WEB_FETCH_DEBUG, "Fetch: Creating network error response with message: {}", message);
     auto response = Response::create(vm);
     response->set_status(0);
     response->set_type(Type::Error);
@@ -72,7 +72,7 @@ GC::Ref<Response> Response::appropriate_network_error(JS::VM& vm, FetchParams co
     // 2. Return an aborted network error if fetchParams is aborted; otherwise return a network error.
     return fetch_params.is_aborted()
         ? aborted_network_error(vm)
-        : network_error(vm, "Fetch has been terminated"sv);
+        : network_error(vm, "Fetch has been terminated"_string);
 }
 
 // https://fetch.spec.whatwg.org/#concept-aborted-network-error
@@ -341,12 +341,6 @@ u64 Response::stale_while_revalidate_lifetime() const
 }
 
 // Non-standard
-Optional<StringView> Response::network_error_message() const
-{
-    if (!m_network_error_message.has_value())
-        return {};
-    return m_network_error_message->visit([](auto const& s) -> StringView { return s; });
-}
 
 FilteredResponse::FilteredResponse(GC::Ref<Response> internal_response, GC::Ref<HeaderList> header_list)
     : Response(header_list)

+ 3 - 3
Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h

@@ -58,7 +58,7 @@ public:
 
     [[nodiscard]] static GC::Ref<Response> create(JS::VM&);
     [[nodiscard]] static GC::Ref<Response> aborted_network_error(JS::VM&);
-    [[nodiscard]] static GC::Ref<Response> network_error(JS::VM&, Variant<String, StringView> message);
+    [[nodiscard]] static GC::Ref<Response> network_error(JS::VM&, String message);
     [[nodiscard]] static GC::Ref<Response> appropriate_network_error(JS::VM&, FetchParams const&);
 
     virtual ~Response() = default;
@@ -124,7 +124,7 @@ public:
     [[nodiscard]] bool is_stale() const;
 
     // Non-standard
-    [[nodiscard]] Optional<StringView> network_error_message() const;
+    [[nodiscard]] Optional<String> const& network_error_message() const { return m_network_error_message; }
     MonotonicTime response_time() const { return m_response_time; }
 
 protected:
@@ -201,7 +201,7 @@ private:
     ByteBuffer m_method;
     MonotonicTime m_response_time;
 
-    Optional<Variant<String, StringView>> m_network_error_message;
+    Optional<String> m_network_error_message;
 
 public:
     [[nodiscard]] ByteBuffer const& method() const { return m_method; }

+ 1 - 1
Libraries/LibWeb/Fetch/Response.cpp

@@ -173,7 +173,7 @@ GC::Ref<Response> Response::error(JS::VM& vm)
 {
     // The static error() method steps are to return the result of creating a Response object, given a new network error, "immutable", and this’s relevant Realm.
     // FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
-    return Response::create(*vm.current_realm(), Infrastructure::Response::network_error(vm, "Response created via `Response.error()`"sv), Headers::Guard::Immutable);
+    return Response::create(*vm.current_realm(), Infrastructure::Response::network_error(vm, "Response created via `Response.error()`"_string), Headers::Guard::Immutable);
 }
 
 // https://fetch.spec.whatwg.org/#dom-response-redirect

+ 2 - 2
Libraries/LibWeb/HTML/HTMLMediaElement.cpp

@@ -1032,8 +1032,8 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::fetch_resource(URL::URL const& url_r
             // 4. If the result of verifying response given the current media resource and byteRange is false, then abort these steps.
             // NOTE: We do this step before creating the updateMedia task so that we can invoke the failure callback.
             if (!verify_response(response, byte_range)) {
-                auto error_message = response->network_error_message().value_or("Failed to fetch media resource"sv);
-                failure_callback(String::from_utf8(error_message).release_value_but_fixme_should_propagate_errors());
+                auto error_message = response->network_error_message().value_or("Failed to fetch media resource"_string);
+                failure_callback(error_message);
                 return;
             }
 

+ 3 - 3
Libraries/LibWeb/HTML/Navigable.cpp

@@ -980,7 +980,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
 
         // 3. If the result of should navigation request of type be blocked by Content Security Policy? given request and cspNavigationType is "Blocked", then set response to a network error and break. [CSP]
         if (ContentSecurityPolicy::should_navigation_request_of_type_be_blocked_by_content_security_policy(request, csp_navigation_type) == ContentSecurityPolicy::Directives::Directive::Result::Blocked) {
-            response_holder->set_response(Fetch::Infrastructure::Response::network_error(vm, "Blocked by Content Security Policy"sv));
+            response_holder->set_response(Fetch::Infrastructure::Response::network_error(vm, "Blocked by Content Security Policy"_string));
             break;
         }
 
@@ -1144,7 +1144,7 @@ static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation
     //     then return null.
     if (response_holder->response()->is_network_error()) {
         // AD-HOC: We pass the error message if we have one in NullWithError
-        if (response_holder->response()->network_error_message().has_value() && !response_holder->response()->network_error_message().value().is_null())
+        if (response_holder->response()->network_error_message().has_value())
             return response_holder->response()->network_error_message().value();
         else
             return Navigable::NullOrError {};
@@ -1312,7 +1312,7 @@ WebIDL::ExceptionOr<void> Navigable::populate_session_history_entry_document(
                 },
                 [](GC::Ref<NonFetchSchemeNavigationParams>) { return false; })) {
             // 1. Set entry's document state's document to the result of creating a document for inline content that doesn't have a DOM, given navigable, null, navTimingType, and userInvolvement. The inline content should indicate to the user the sort of error that occurred.
-            auto error_message = navigation_params.has<NullOrError>() ? navigation_params.get<NullOrError>().value_or("Unknown error"sv) : "The request was denied."sv;
+            auto error_message = navigation_params.has<NullOrError>() ? navigation_params.get<NullOrError>().value_or("Unknown error"_string) : "The request was denied."_string;
 
             auto error_html = load_error_page(entry->url(), error_message).release_value_but_fixme_should_propagate_errors();
             entry->document_state()->set_document(create_document_for_inline_content(this, navigation_id, user_involvement, [this, error_html](auto& document) {

+ 1 - 1
Libraries/LibWeb/HTML/Navigable.h

@@ -42,7 +42,7 @@ class Navigable : public JS::Cell
 public:
     virtual ~Navigable() override;
 
-    using NullOrError = Optional<StringView>;
+    using NullOrError = Optional<String>;
     using NavigationParamsVariant = Variant<NullOrError, GC::Ref<NavigationParams>, GC::Ref<NonFetchSchemeNavigationParams>>;
 
     ErrorOr<void> initialize_navigable(GC::Ref<DocumentState> document_state, GC::Ptr<Navigable> parent);

+ 5 - 5
Libraries/LibWeb/XHR/XMLHttpRequest.cpp

@@ -63,7 +63,7 @@ WebIDL::ExceptionOr<GC::Ref<XMLHttpRequest>> XMLHttpRequest::construct_impl(JS::
 {
     auto upload_object = realm.create<XMLHttpRequestUpload>(realm);
     auto author_request_headers = Fetch::Infrastructure::HeaderList::create(realm.vm());
-    auto response = Fetch::Infrastructure::Response::network_error(realm.vm(), "Not sent yet"sv);
+    auto response = Fetch::Infrastructure::Response::network_error(realm.vm(), "Not sent yet"_string);
     auto fetch_controller = Fetch::Infrastructure::FetchController::create(realm.vm());
     return realm.create<XMLHttpRequest>(realm, *upload_object, *author_request_headers, *response, *fetch_controller);
 }
@@ -529,7 +529,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::open(String const& method_string, Stri
     // Empty this’s author request headers.
     m_author_request_headers->clear();
     // Set this’s response to a network error.
-    m_response = Fetch::Infrastructure::Response::network_error(realm().vm(), "Not yet sent"sv);
+    m_response = Fetch::Infrastructure::Response::network_error(realm().vm(), "Not yet sent"_string);
     // Set this’s received bytes to the empty byte sequence.
     m_received_bytes = {};
     // Set this’s response object to null.
@@ -845,7 +845,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
             auto process_body_error = GC::create_function(heap(), [this](JS::Value) {
                 auto& vm = this->vm();
                 // 1. Set this’s response to a network error.
-                m_response = Fetch::Infrastructure::Response::network_error(vm, "A network error occurred processing body."sv);
+                m_response = Fetch::Infrastructure::Response::network_error(vm, "A network error occurred processing body."_string);
                 // 2. Run handle errors for this.
                 // NOTE: This cannot throw, as `handle_errors` only throws in a synchronous context.
                 // FIXME: However, we can receive allocation failures, but we can't propagate them anywhere currently.
@@ -1140,7 +1140,7 @@ void XMLHttpRequest::abort()
     // Spec Note: No readystatechange event is dispatched.
     if (m_state == State::Done) {
         m_state = State::Unsent;
-        m_response = Fetch::Infrastructure::Response::network_error(vm(), "Not yet sent"sv);
+        m_response = Fetch::Infrastructure::Response::network_error(vm(), "Not yet sent"_string);
     }
 }
 
@@ -1245,7 +1245,7 @@ JS::ThrowCompletionOr<void> XMLHttpRequest::request_error_steps(FlyString const&
     m_send = false;
 
     // 3. Set xhr’s response to a network error.
-    m_response = Fetch::Infrastructure::Response::network_error(realm().vm(), "Failed to load"sv);
+    m_response = Fetch::Infrastructure::Response::network_error(realm().vm(), "Failed to load"_string);
 
     // 4. If xhr’s synchronous flag is set, then throw exception.
     if (m_synchronous) {

+ 0 - 2
Meta/gn/secondary/AK/BUILD.gn

@@ -61,8 +61,6 @@ shared_library("AK") {
     "DateConstants.h",
     "DefaultDelete.h",
     "Demangle.h",
-    "DeprecatedFlyString.cpp",
-    "DeprecatedFlyString.h",
     "Diagnostics.h",
     "DisjointChunks.h",
     "DistinctNumeric.h",

+ 1 - 1
Services/WebWorker/DedicatedWorkerHost.cpp

@@ -124,7 +124,7 @@ void DedicatedWorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHo
             // 3. If the Run CSP initialization for a global object algorithm returns "Blocked" when executed upon worker
             //    global scope, set response to a network error. [CSP]
             if (worker_global_scope->run_csp_initialization() == Web::ContentSecurityPolicy::Directives::Directive::Result::Blocked) {
-                response = Web::Fetch::Infrastructure::Response::network_error(vm, "Blocked by Content Security Policy"sv);
+                response = Web::Fetch::Infrastructure::Response::network_error(vm, "Blocked by Content Security Policy"_string);
             }
 
             // FIXME: 4. If worker global scope's embedder policy's value is compatible with cross-origin isolation and is shared is true,

+ 0 - 21
Tests/AK/TestByteString.cpp

@@ -7,7 +7,6 @@
 #include <LibTest/TestCase.h>
 
 #include <AK/ByteString.h>
-#include <AK/DeprecatedFlyString.h>
 #include <AK/StringBuilder.h>
 #include <AK/Vector.h>
 #include <cstring>
@@ -139,26 +138,6 @@ TEST_CASE(to_uppercase)
     EXPECT(ByteString("AbC").to_uppercase() == "ABC");
 }
 
-TEST_CASE(flystring)
-{
-    {
-        DeprecatedFlyString a("foo");
-        DeprecatedFlyString b("foo");
-        EXPECT_EQ(a.impl(), b.impl());
-    }
-
-    {
-        ByteString a = "foo";
-        DeprecatedFlyString b = a;
-        StringBuilder builder;
-        builder.append('f');
-        builder.append("oo"sv);
-        DeprecatedFlyString c = builder.to_byte_string();
-        EXPECT_EQ(a.impl(), b.impl());
-        EXPECT_EQ(a.impl(), c.impl());
-    }
-}
-
 TEST_CASE(replace)
 {
     ByteString test_string = "Well, hello Friends!";

+ 0 - 4
Tests/AK/TestStringUtils.cpp

@@ -23,11 +23,7 @@ TEST_CASE(hash_compatible)
     static_assert(AK::Concepts::HashCompatible<FlyString, StringView>);
 
     static_assert(AK::Concepts::HashCompatible<ByteString, StringView>);
-    static_assert(AK::Concepts::HashCompatible<ByteString, DeprecatedFlyString>);
     static_assert(AK::Concepts::HashCompatible<StringView, ByteString>);
-    static_assert(AK::Concepts::HashCompatible<StringView, DeprecatedFlyString>);
-    static_assert(AK::Concepts::HashCompatible<DeprecatedFlyString, ByteString>);
-    static_assert(AK::Concepts::HashCompatible<DeprecatedFlyString, StringView>);
 
     static_assert(AK::Concepts::HashCompatible<StringView, ByteBuffer>);
     static_assert(AK::Concepts::HashCompatible<ByteBuffer, StringView>);

+ 1 - 1
Utilities/js.cpp

@@ -795,7 +795,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
 
                 for (auto const& name : global_environment.declarative_record().bindings()) {
                     if (name.bytes_as_string_view().starts_with(variable_name)) {
-                        results.empend(name.to_deprecated_fly_string());
+                        results.empend(name);
                         results.last().invariant_offset = variable_name.bytes().size();
                     }
                 }