From 4b064097bd3412e81910a9d2f08fd875f333d643 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Thu, 27 May 2021 23:13:39 -0400 Subject: [PATCH 1/2] applets/swkbd: Only read the text check message on Failure/Confirm Applications may leave this region of memory uninitialized when the text check result is not either Failure or Confirm. Attempting to read uninitialized memory may cause an exception within the UTF16 to UTF8 string converter. Fix this by only reading the text check message on Failure or Confirm. --- src/core/hle/service/am/applets/software_keyboard.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index b05a5da04a..a1027a9ad5 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -273,8 +273,13 @@ void SoftwareKeyboard::ProcessTextCheck() { std::memcpy(&swkbd_text_check, text_check_data.data(), sizeof(SwkbdTextCheck)); - std::u16string text_check_message = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_text_check.text_check_message.data(), swkbd_text_check.text_check_message.size()); + std::u16string text_check_message = + swkbd_text_check.text_check_result == SwkbdTextCheckResult::Failure || + swkbd_text_check.text_check_result == SwkbdTextCheckResult::Confirm + ? Common::UTF16StringFromFixedZeroTerminatedBuffer( + swkbd_text_check.text_check_message.data(), + swkbd_text_check.text_check_message.size()) + : u""; LOG_INFO(Service_AM, "\nTextCheckResult: {}\nTextCheckMessage: {}", GetTextCheckResultName(swkbd_text_check.text_check_result), From ed52a835115455fbb19942f78d448c0a6306e8b5 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Thu, 27 May 2021 23:22:38 -0400 Subject: [PATCH 2/2] applets/swkbd: Make use of std::move where applicable Avoids redundant string copies --- .../service/am/applets/software_keyboard.cpp | 16 ++++++------ src/yuzu/applets/software_keyboard.cpp | 25 ++++++++----------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index a1027a9ad5..b1a81810b3 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -290,10 +290,10 @@ void SoftwareKeyboard::ProcessTextCheck() { SubmitNormalOutputAndExit(SwkbdResult::Ok, current_text); break; case SwkbdTextCheckResult::Failure: - ShowTextCheckDialog(SwkbdTextCheckResult::Failure, text_check_message); + ShowTextCheckDialog(SwkbdTextCheckResult::Failure, std::move(text_check_message)); break; case SwkbdTextCheckResult::Confirm: - ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, text_check_message); + ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, std::move(text_check_message)); break; case SwkbdTextCheckResult::Silent: default: @@ -487,7 +487,7 @@ void SoftwareKeyboard::InitializeFrontendKeyboard() { max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box; Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{ok_text}, + .ok_text{std::move(ok_text)}, .header_text{}, .sub_text{}, .guide_text{}, @@ -563,10 +563,10 @@ void SoftwareKeyboard::InitializeFrontendKeyboard() { : false; Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{ok_text}, - .header_text{header_text}, - .sub_text{sub_text}, - .guide_text{guide_text}, + .ok_text{std::move(ok_text)}, + .header_text{std::move(header_text)}, + .sub_text{std::move(sub_text)}, + .guide_text{std::move(guide_text)}, .initial_text{initial_text}, .max_text_length{max_text_length}, .min_text_length{min_text_length}, @@ -595,7 +595,7 @@ void SoftwareKeyboard::ShowNormalKeyboard() { void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_result, std::u16string text_check_message) { - frontend.ShowTextCheckDialog(text_check_result, text_check_message); + frontend.ShowTextCheckDialog(text_check_result, std::move(text_check_message)); } void SoftwareKeyboard::ShowInlineKeyboard() { diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/software_keyboard.cpp index a9a095d588..aa453a79fb 100644 --- a/src/yuzu/applets/software_keyboard.cpp +++ b/src/yuzu/applets/software_keyboard.cpp @@ -1101,12 +1101,11 @@ void QtSoftwareKeyboardDialog::NormalKeyboardButtonClicked(QPushButton* button) } if (button == ui->button_ok || button == ui->button_ok_shift || button == ui->button_ok_num) { - if (ui->topOSK->currentIndex() == 1) { - emit SubmitNormalText(SwkbdResult::Ok, - ui->text_edit_osk->toPlainText().toStdU16String()); - } else { - emit SubmitNormalText(SwkbdResult::Ok, ui->line_edit_osk->text().toStdU16String()); - } + auto text = ui->topOSK->currentIndex() == 1 + ? ui->text_edit_osk->toPlainText().toStdU16String() + : ui->line_edit_osk->text().toStdU16String(); + + emit SubmitNormalText(SwkbdResult::Ok, std::move(text)); return; } @@ -1265,13 +1264,11 @@ void QtSoftwareKeyboardDialog::TranslateButtonPress(HIDButton button) { if (is_inline) { emit SubmitInlineText(SwkbdReplyType::DecidedCancel, current_text, cursor_position); } else { - if (ui->topOSK->currentIndex() == 1) { - emit SubmitNormalText(SwkbdResult::Cancel, - ui->text_edit_osk->toPlainText().toStdU16String()); - } else { - emit SubmitNormalText(SwkbdResult::Cancel, - ui->line_edit_osk->text().toStdU16String()); - } + auto text = ui->topOSK->currentIndex() == 1 + ? ui->text_edit_osk->toPlainText().toStdU16String() + : ui->line_edit_osk->text().toStdU16String(); + + emit SubmitNormalText(SwkbdResult::Cancel, std::move(text)); } break; case HIDButton::Y: @@ -1563,7 +1560,7 @@ void QtSoftwareKeyboard::ShowNormalKeyboard() const { void QtSoftwareKeyboard::ShowTextCheckDialog( Service::AM::Applets::SwkbdTextCheckResult text_check_result, std::u16string text_check_message) const { - emit MainWindowShowTextCheckDialog(text_check_result, text_check_message); + emit MainWindowShowTextCheckDialog(text_check_result, std::move(text_check_message)); } void QtSoftwareKeyboard::ShowInlineKeyboard(