mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
Ladybird/AppKit: Sanitize user-provided URLs with LibWebView
This commit is contained in:
parent
f023e37de7
commit
aa5cd24c90
Notes:
sideshowbarker
2024-07-17 02:37:08 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/aa5cd24c90 Pull-request: https://github.com/SerenityOS/serenity/pull/21435 Reviewed-by: https://github.com/ADKaster ✅
7 changed files with 58 additions and 95 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <AK/Optional.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/URL.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibWeb/CSS/PreferredColorScheme.h>
|
||||
#include <LibWeb/HTML/ActivateTab.h>
|
||||
#include <LibWebView/CookieJar.h>
|
||||
|
@ -20,7 +21,8 @@
|
|||
|
||||
@interface ApplicationDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
- (nullable instancetype)init:(Optional<URL>)initial_url
|
||||
- (nullable instancetype)init:(Vector<URL>)initial_urls
|
||||
newTabPageURL:(URL)new_tab_page_url
|
||||
withCookieJar:(WebView::CookieJar)cookie_jar
|
||||
webdriverContentIPCPath:(StringView)webdriver_content_ipc_path;
|
||||
|
||||
|
|
|
@ -4,15 +4,12 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <BrowserSettings/Defaults.h>
|
||||
|
||||
#import <Application/ApplicationDelegate.h>
|
||||
#import <LibWebView/UserAgent.h>
|
||||
#import <UI/LadybirdWebView.h>
|
||||
#import <UI/Tab.h>
|
||||
#import <UI/TabController.h>
|
||||
#import <Utilities/Conversions.h>
|
||||
#import <Utilities/URL.h>
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
# error "This project requires ARC"
|
||||
|
@ -20,7 +17,7 @@
|
|||
|
||||
@interface ApplicationDelegate ()
|
||||
{
|
||||
Optional<URL> m_initial_url;
|
||||
Vector<URL> m_initial_urls;
|
||||
URL m_new_tab_page_url;
|
||||
|
||||
// This will always be populated, but we cannot have a non-default constructible instance variable.
|
||||
|
@ -47,7 +44,8 @@
|
|||
|
||||
@implementation ApplicationDelegate
|
||||
|
||||
- (instancetype)init:(Optional<URL>)initial_url
|
||||
- (instancetype)init:(Vector<URL>)initial_urls
|
||||
newTabPageURL:(URL)new_tab_page_url
|
||||
withCookieJar:(WebView::CookieJar)cookie_jar
|
||||
webdriverContentIPCPath:(StringView)webdriver_content_ipc_path
|
||||
{
|
||||
|
@ -66,8 +64,8 @@
|
|||
|
||||
self.managed_tabs = [[NSMutableArray alloc] init];
|
||||
|
||||
m_initial_url = move(initial_url);
|
||||
m_new_tab_page_url = Ladybird::rebase_url_on_serenity_resource_root(Browser::default_new_tab_url);
|
||||
m_initial_urls = move(initial_urls);
|
||||
m_new_tab_page_url = move(new_tab_page_url);
|
||||
|
||||
m_cookie_jar = move(cookie_jar);
|
||||
|
||||
|
@ -481,9 +479,19 @@
|
|||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification*)notification
|
||||
{
|
||||
[self createNewTab:m_initial_url
|
||||
fromTab:nil
|
||||
activateTab:Web::HTML::ActivateTab::Yes];
|
||||
Tab* tab = nil;
|
||||
|
||||
for (auto const& url : m_initial_urls) {
|
||||
auto activate_tab = tab == nil ? Web::HTML::ActivateTab::Yes : Web::HTML::ActivateTab::No;
|
||||
|
||||
auto* controller = [self createNewTab:url
|
||||
fromTab:tab
|
||||
activateTab:activate_tab];
|
||||
|
||||
tab = (Tab*)[controller window];
|
||||
}
|
||||
|
||||
m_initial_urls.clear();
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification*)notification
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <LibWebView/History.h>
|
||||
#include <LibWebView/URL.h>
|
||||
|
||||
#import <Application/ApplicationDelegate.h>
|
||||
#import <LibWeb/Loader/ResourceLoader.h>
|
||||
|
@ -13,7 +14,6 @@
|
|||
#import <UI/Tab.h>
|
||||
#import <UI/TabController.h>
|
||||
#import <Utilities/Conversions.h>
|
||||
#import <Utilities/URL.h>
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
# error "This project requires ARC"
|
||||
|
@ -600,9 +600,11 @@ enum class IsHistoryNavigation {
|
|||
return NO;
|
||||
}
|
||||
|
||||
auto* url_string = [[text_view textStorage] string];
|
||||
auto url = Ladybird::sanitize_url(url_string);
|
||||
[self loadURL:url];
|
||||
auto url_string = Ladybird::ns_string_to_string([[text_view textStorage] string]);
|
||||
|
||||
if (auto url = WebView::sanitize_url(url_string); url.has_value()) {
|
||||
[self loadURL:*url];
|
||||
}
|
||||
|
||||
[self.window makeFirstResponder:nil];
|
||||
return YES;
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/URL.h>
|
||||
|
||||
#import <System/Cocoa.h>
|
||||
|
||||
namespace Ladybird {
|
||||
|
||||
URL sanitize_url(NSString*);
|
||||
URL sanitize_url(StringView);
|
||||
|
||||
URL rebase_url_on_serenity_resource_root(StringView);
|
||||
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <Ladybird/Utilities.h>
|
||||
#include <LibFileSystem/FileSystem.h>
|
||||
|
||||
#import <Utilities/URL.h>
|
||||
|
||||
namespace Ladybird {
|
||||
|
||||
URL sanitize_url(StringView url_string)
|
||||
{
|
||||
if (url_string.starts_with('/') || FileSystem::exists(url_string))
|
||||
return MUST(String::formatted("file://{}", MUST(FileSystem::real_path(url_string))));
|
||||
|
||||
URL url { url_string };
|
||||
if (!url.is_valid())
|
||||
url = MUST(String::formatted("https://{}", url_string));
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
URL sanitize_url(NSString* url_string)
|
||||
{
|
||||
auto const* utf8 = [url_string UTF8String];
|
||||
return sanitize_url({ utf8, strlen(utf8) });
|
||||
}
|
||||
|
||||
URL rebase_url_on_serenity_resource_root(StringView url_string)
|
||||
{
|
||||
URL url { url_string };
|
||||
Vector<DeprecatedString> paths;
|
||||
|
||||
for (auto segment : s_serenity_resource_root.split('/'))
|
||||
paths.append(move(segment));
|
||||
|
||||
for (size_t i = 0; i < url.path_segment_count(); ++i)
|
||||
paths.append(url.path_segment_at_index(i));
|
||||
|
||||
url.set_paths(move(paths));
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <BrowserSettings/Defaults.h>
|
||||
#include <Ladybird/Utilities.h>
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
|
@ -11,18 +12,34 @@
|
|||
#include <LibMain/Main.h>
|
||||
#include <LibWebView/CookieJar.h>
|
||||
#include <LibWebView/Database.h>
|
||||
#include <LibWebView/URL.h>
|
||||
|
||||
#import <Application/Application.h>
|
||||
#import <Application/ApplicationDelegate.h>
|
||||
#import <Application/EventLoopImplementation.h>
|
||||
#import <UI/Tab.h>
|
||||
#import <UI/TabController.h>
|
||||
#import <Utilities/URL.h>
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
# error "This project requires ARC"
|
||||
#endif
|
||||
|
||||
static URL rebase_url_on_serenity_resource_root(StringView url_string)
|
||||
{
|
||||
URL url { url_string };
|
||||
Vector<DeprecatedString> paths;
|
||||
|
||||
for (auto segment : s_serenity_resource_root.split('/'))
|
||||
paths.append(move(segment));
|
||||
|
||||
for (size_t i = 0; i < url.path_segment_count(); ++i)
|
||||
paths.append(url.path_segment_at_index(i));
|
||||
|
||||
url.set_paths(move(paths));
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
[Application sharedApplication];
|
||||
|
@ -36,12 +53,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
Gfx::FontDatabase::set_default_font_query("Katica 10 400 0");
|
||||
Gfx::FontDatabase::set_fixed_width_font_query("Csilla 10 400 0");
|
||||
|
||||
StringView url;
|
||||
Vector<StringView> raw_urls;
|
||||
StringView webdriver_content_ipc_path;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.set_general_help("The Ladybird web browser");
|
||||
args_parser.add_positional_argument(url, "URL to open", "url", Core::ArgsParser::Required::No);
|
||||
args_parser.add_positional_argument(raw_urls, "URLs to open", "url", Core::ArgsParser::Required::No);
|
||||
args_parser.add_option(webdriver_content_ipc_path, "Path to WebDriver IPC for WebContent", "webdriver-content-path", 0, "path", Core::ArgsParser::OptionHideMode::CommandLineAndMarkdown);
|
||||
args_parser.parse(arguments);
|
||||
|
||||
|
@ -49,12 +66,19 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|||
auto database = TRY(WebView::Database::create(move(sql_server_paths)));
|
||||
auto cookie_jar = TRY(WebView::CookieJar::create(*database));
|
||||
|
||||
Optional<URL> initial_url;
|
||||
if (auto parsed_url = Ladybird::sanitize_url(url); parsed_url.is_valid()) {
|
||||
initial_url = move(parsed_url);
|
||||
auto new_tab_page_url = rebase_url_on_serenity_resource_root(Browser::default_new_tab_url);
|
||||
Vector<URL> initial_urls;
|
||||
|
||||
for (auto const& raw_url : raw_urls) {
|
||||
if (auto url = WebView::sanitize_url(raw_url); url.has_value())
|
||||
initial_urls.append(url.release_value());
|
||||
}
|
||||
|
||||
auto* delegate = [[ApplicationDelegate alloc] init:move(initial_url)
|
||||
if (initial_urls.is_empty())
|
||||
initial_urls.append(new_tab_page_url);
|
||||
|
||||
auto* delegate = [[ApplicationDelegate alloc] init:move(initial_urls)
|
||||
newTabPageURL:move(new_tab_page_url)
|
||||
withCookieJar:move(cookie_jar)
|
||||
webdriverContentIPCPath:webdriver_content_ipc_path];
|
||||
|
||||
|
|
|
@ -145,7 +145,6 @@ elseif (APPLE)
|
|||
AppKit/UI/TabController.mm
|
||||
AppKit/Utilities/Conversions.mm
|
||||
AppKit/Utilities/NSString+Ladybird.mm
|
||||
AppKit/Utilities/URL.mm
|
||||
)
|
||||
target_include_directories(ladybird PRIVATE AppKit)
|
||||
target_link_libraries(ladybird PRIVATE ${COCOA_LIBRARY} LibUnicode)
|
||||
|
|
Loading…
Reference in a new issue