瀏覽代碼

Browser+Ladybird+LibWeb: Prevent infinite growth of content filters

We never clear content filters on either end of the Browser-WebContent
IPC connection. So when the filters change, we re-append all filters to
the Vector holding them. This incidentally makes it impossible to remove
a filter.

Change both sides to clear their filter lists when receiving a new set
of filters.
Timothy Flynn 2 年之前
父節點
當前提交
76ae60da15

+ 12 - 3
Ladybird/WebContent/main.cpp

@@ -121,15 +121,24 @@ static ErrorOr<void> load_content_filters()
         file_or_error = Core::File::open(DeprecatedString::formatted("{}/res/ladybird/BrowserContentFilters.txt", s_serenity_resource_root), Core::File::OpenMode::Read);
     if (file_or_error.is_error())
         return file_or_error.release_error();
+
     auto file = file_or_error.release_value();
     auto ad_filter_list = TRY(Core::BufferedFile::create(move(file)));
     auto buffer = TRY(ByteBuffer::create_uninitialized(4096));
+
+    Vector<DeprecatedString> patterns;
+
     while (TRY(ad_filter_list->can_read_line())) {
         auto line = TRY(ad_filter_list->read_line(buffer));
-        if (!line.is_empty()) {
-            Web::ContentFilter::the().add_pattern(line);
-        }
+        if (line.is_empty())
+            continue;
+
+        TRY(patterns.try_append(line));
     }
+
+    auto& content_filter = Web::ContentFilter::the();
+    TRY(content_filter.set_patterns(patterns));
+
     return {};
 }
 

+ 3 - 0
Userland/Applications/Browser/main.cpp

@@ -50,6 +50,9 @@ static ErrorOr<void> load_content_filters()
     auto file = TRY(Core::File::open(DeprecatedString::formatted("{}/BrowserContentFilters.txt", Core::StandardPaths::config_directory()), Core::File::OpenMode::Read));
     auto ad_filter_list = TRY(Core::BufferedFile::create(move(file)));
     auto buffer = TRY(ByteBuffer::create_uninitialized(4096));
+
+    Browser::g_content_filters.clear_with_capacity();
+
     while (TRY(ad_filter_list->can_read_line())) {
         auto line = TRY(ad_filter_list->read_line(buffer));
         if (!line.is_empty())

+ 16 - 8
Userland/Libraries/LibWeb/Loader/ContentFilter.cpp

@@ -33,15 +33,23 @@ bool ContentFilter::is_filtered(const AK::URL& url) const
     return false;
 }
 
-void ContentFilter::add_pattern(DeprecatedString const& pattern)
+ErrorOr<void> ContentFilter::set_patterns(ReadonlySpan<DeprecatedString> patterns)
 {
-    StringBuilder builder;
-    if (!pattern.starts_with('*'))
-        builder.append('*');
-    builder.append(pattern);
-    if (!pattern.ends_with('*'))
-        builder.append('*');
-    m_patterns.empend(builder.to_deprecated_string());
+    m_patterns.clear_with_capacity();
+
+    for (auto const& pattern : patterns) {
+        StringBuilder builder;
+
+        if (!pattern.starts_with('*'))
+            TRY(builder.try_append('*'));
+        TRY(builder.try_append(pattern));
+        if (!pattern.ends_with('*'))
+            TRY(builder.try_append('*'));
+
+        TRY(m_patterns.try_empend(builder.to_deprecated_string()));
+    }
+
+    return {};
 }
 
 }

+ 1 - 1
Userland/Libraries/LibWeb/Loader/ContentFilter.h

@@ -16,7 +16,7 @@ public:
     static ContentFilter& the();
 
     bool is_filtered(const AK::URL&) const;
-    void add_pattern(DeprecatedString const&);
+    ErrorOr<void> set_patterns(ReadonlySpan<DeprecatedString>);
 
 private:
     ContentFilter();

+ 1 - 2
Userland/Services/WebContent/ConnectionFromClient.cpp

@@ -636,8 +636,7 @@ Messages::WebContentServer::DumpLayoutTreeResponse ConnectionFromClient::dump_la
 
 void ConnectionFromClient::set_content_filters(Vector<DeprecatedString> const& filters)
 {
-    for (auto& filter : filters)
-        Web::ContentFilter::the().add_pattern(filter);
+    Web::ContentFilter::the().set_patterns(filters).release_value_but_fixme_should_propagate_errors();
 }
 
 void ConnectionFromClient::set_autoplay_allowed_on_all_websites()