applets/web: Fix a use-after-free when passing in the URL string

The URL string was being deleted before being used, leading to a use-after-free occurring when it is used afterwards.

Fix this by taking the string by const ref to extend its lifetime, ensuring it doesn't get deleted before use.
This commit is contained in:
Morph 2021-04-28 11:32:44 -04:00
parent b096ec68cd
commit 0af182baa2
6 changed files with 28 additions and 25 deletions

View file

@ -12,7 +12,7 @@ WebBrowserApplet::~WebBrowserApplet() = default;
DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default; DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default;
void DefaultWebBrowserApplet::OpenLocalWebPage( void DefaultWebBrowserApplet::OpenLocalWebPage(
std::string_view local_url, std::function<void()> extract_romfs_callback, const std::string& local_url, std::function<void()> extract_romfs_callback,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const { std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const {
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open local web page at {}", LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open local web page at {}",
local_url); local_url);
@ -21,7 +21,7 @@ void DefaultWebBrowserApplet::OpenLocalWebPage(
} }
void DefaultWebBrowserApplet::OpenExternalWebPage( void DefaultWebBrowserApplet::OpenExternalWebPage(
std::string_view external_url, const std::string& external_url,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const { std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const {
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open external web page at {}", LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open external web page at {}",
external_url); external_url);

View file

@ -16,11 +16,11 @@ public:
virtual ~WebBrowserApplet(); virtual ~WebBrowserApplet();
virtual void OpenLocalWebPage( virtual void OpenLocalWebPage(
std::string_view local_url, std::function<void()> extract_romfs_callback, const std::string& local_url, std::function<void()> extract_romfs_callback,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0; std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0;
virtual void OpenExternalWebPage( virtual void OpenExternalWebPage(
std::string_view external_url, const std::string& external_url,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0; std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0;
}; };
@ -28,11 +28,12 @@ class DefaultWebBrowserApplet final : public WebBrowserApplet {
public: public:
~DefaultWebBrowserApplet() override; ~DefaultWebBrowserApplet() override;
void OpenLocalWebPage(std::string_view local_url, std::function<void()> extract_romfs_callback, void OpenLocalWebPage(const std::string& local_url,
std::function<void()> extract_romfs_callback,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> std::function<void(Service::AM::Applets::WebExitReason, std::string)>
callback) const override; callback) const override;
void OpenExternalWebPage(std::string_view external_url, void OpenExternalWebPage(const std::string& external_url,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> std::function<void(Service::AM::Applets::WebExitReason, std::string)>
callback) const override; callback) const override;
}; };

View file

@ -102,8 +102,8 @@ QtNXWebEngineView::~QtNXWebEngineView() {
StopInputThread(); StopInputThread();
} }
void QtNXWebEngineView::LoadLocalWebPage(std::string_view main_url, void QtNXWebEngineView::LoadLocalWebPage(const std::string& main_url,
std::string_view additional_args) { const std::string& additional_args) {
is_local = true; is_local = true;
LoadExtractedFonts(); LoadExtractedFonts();
@ -113,12 +113,12 @@ void QtNXWebEngineView::LoadLocalWebPage(std::string_view main_url,
SetLastURL("http://localhost/"); SetLastURL("http://localhost/");
StartInputThread(); StartInputThread();
load(QUrl(QUrl::fromLocalFile(QString::fromStdString(std::string(main_url))).toString() + load(QUrl(QUrl::fromLocalFile(QString::fromStdString(main_url)).toString() +
QString::fromStdString(std::string(additional_args)))); QString::fromStdString(additional_args)));
} }
void QtNXWebEngineView::LoadExternalWebPage(std::string_view main_url, void QtNXWebEngineView::LoadExternalWebPage(const std::string& main_url,
std::string_view additional_args) { const std::string& additional_args) {
is_local = false; is_local = false;
SetUserAgent(UserAgent::WebApplet); SetUserAgent(UserAgent::WebApplet);
@ -127,8 +127,7 @@ void QtNXWebEngineView::LoadExternalWebPage(std::string_view main_url,
SetLastURL("http://localhost/"); SetLastURL("http://localhost/");
StartInputThread(); StartInputThread();
load(QUrl(QString::fromStdString(std::string(main_url)) + load(QUrl(QString::fromStdString(main_url) + QString::fromStdString(additional_args)));
QString::fromStdString(std::string(additional_args))));
} }
void QtNXWebEngineView::SetUserAgent(UserAgent user_agent) { void QtNXWebEngineView::SetUserAgent(UserAgent user_agent) {
@ -375,7 +374,7 @@ QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {
QtWebBrowser::~QtWebBrowser() = default; QtWebBrowser::~QtWebBrowser() = default;
void QtWebBrowser::OpenLocalWebPage( void QtWebBrowser::OpenLocalWebPage(
std::string_view local_url, std::function<void()> extract_romfs_callback_, const std::string& local_url, std::function<void()> extract_romfs_callback_,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback_) const { std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback_) const {
extract_romfs_callback = std::move(extract_romfs_callback_); extract_romfs_callback = std::move(extract_romfs_callback_);
callback = std::move(callback_); callback = std::move(callback_);
@ -390,7 +389,7 @@ void QtWebBrowser::OpenLocalWebPage(
} }
void QtWebBrowser::OpenExternalWebPage( void QtWebBrowser::OpenExternalWebPage(
std::string_view external_url, const std::string& external_url,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback_) const { std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback_) const {
callback = std::move(callback_); callback = std::move(callback_);

View file

@ -58,7 +58,7 @@ public:
* @param main_url The url to the file. * @param main_url The url to the file.
* @param additional_args Additional arguments appended to the main url. * @param additional_args Additional arguments appended to the main url.
*/ */
void LoadLocalWebPage(std::string_view main_url, std::string_view additional_args); void LoadLocalWebPage(const std::string& main_url, const std::string& additional_args);
/** /**
* Loads an external website. Cannot be used to load local urls. * Loads an external website. Cannot be used to load local urls.
@ -66,7 +66,7 @@ public:
* @param main_url The url to the website. * @param main_url The url to the website.
* @param additional_args Additional arguments appended to the main url. * @param additional_args Additional arguments appended to the main url.
*/ */
void LoadExternalWebPage(std::string_view main_url, std::string_view additional_args); void LoadExternalWebPage(const std::string& main_url, const std::string& additional_args);
/** /**
* Sets the background color of the web page. * Sets the background color of the web page.
@ -193,16 +193,17 @@ public:
explicit QtWebBrowser(GMainWindow& parent); explicit QtWebBrowser(GMainWindow& parent);
~QtWebBrowser() override; ~QtWebBrowser() override;
void OpenLocalWebPage(std::string_view local_url, std::function<void()> extract_romfs_callback_, void OpenLocalWebPage(const std::string& local_url,
std::function<void()> extract_romfs_callback_,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> std::function<void(Service::AM::Applets::WebExitReason, std::string)>
callback_) const override; callback_) const override;
void OpenExternalWebPage(std::string_view external_url, void OpenExternalWebPage(const std::string& external_url,
std::function<void(Service::AM::Applets::WebExitReason, std::string)> std::function<void(Service::AM::Applets::WebExitReason, std::string)>
callback_) const override; callback_) const override;
signals: signals:
void MainWindowOpenWebPage(std::string_view main_url, std::string_view additional_args, void MainWindowOpenWebPage(const std::string& main_url, const std::string& additional_args,
bool is_local) const; bool is_local) const;
private: private:

View file

@ -574,8 +574,8 @@ void GMainWindow::SoftwareKeyboardExit() {
software_keyboard = nullptr; software_keyboard = nullptr;
} }
void GMainWindow::WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args, void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
bool is_local) { const std::string& additional_args, bool is_local) {
#ifdef YUZU_USE_QT_WEB_ENGINE #ifdef YUZU_USE_QT_WEB_ENGINE
if (disable_web_applet) { if (disable_web_applet) {
@ -596,13 +596,15 @@ void GMainWindow::WebBrowserOpenWebPage(std::string_view main_url, std::string_v
loading_progress.setRange(0, 3); loading_progress.setRange(0, 3);
loading_progress.setValue(0); loading_progress.setValue(0);
if (is_local && !Common::FS::Exists(std::string(main_url))) { if (is_local && !Common::FS::Exists(main_url)) {
loading_progress.show(); loading_progress.show();
auto future = QtConcurrent::run([this] { emit WebBrowserExtractOfflineRomFS(); }); auto future = QtConcurrent::run([this] { emit WebBrowserExtractOfflineRomFS(); });
while (!future.isFinished()) { while (!future.isFinished()) {
QCoreApplication::processEvents(); QCoreApplication::processEvents();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
} }

View file

@ -159,7 +159,7 @@ public slots:
void SoftwareKeyboardExit(); void SoftwareKeyboardExit();
void ErrorDisplayDisplayError(QString error_code, QString error_text); void ErrorDisplayDisplayError(QString error_code, QString error_text);
void ProfileSelectorSelectProfile(); void ProfileSelectorSelectProfile();
void WebBrowserOpenWebPage(std::string_view main_url, std::string_view additional_args, void WebBrowserOpenWebPage(const std::string& main_url, const std::string& additional_args,
bool is_local); bool is_local);
void OnAppFocusStateChanged(Qt::ApplicationState state); void OnAppFocusStateChanged(Qt::ApplicationState state);