From c823cf6594c2ed8f69c84cabb9ed307496a55eff Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 9 May 2019 20:41:33 -0400 Subject: service/set: Correct and simplify behavior related to copying language codes This corrects cases where it was possible to write more entries into the write buffer than were requested. Now, we check the size of the buffer before actually writing into them. We were also returning the wrong value for GetAvailableLanguageCodeCount2(). This was previously returning 64, but only 17 should have been returned. 64 entries is the size of the static array used in MakeLanguageCode() within the service binary itself, but isn't the actual total number of language codes present. --- src/core/hle/service/set/set.cpp | 56 ++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 4ecb6bcef..298d85011 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -2,16 +2,15 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/client_port.h" -#include "core/hle/kernel/client_session.h" #include "core/hle/service/set/set.h" #include "core/settings.h" namespace Service::Set { - +namespace { constexpr std::array available_language_codes = {{ LanguageCode::JA, LanguageCode::EN_US, @@ -32,41 +31,35 @@ constexpr std::array available_language_codes = {{ LanguageCode::ZH_HANT, }}; -constexpr std::size_t pre4_0_0_max_entries = 0xF; -constexpr std::size_t post4_0_0_max_entries = 0x40; +constexpr std::size_t pre4_0_0_max_entries = 15; +constexpr std::size_t post4_0_0_max_entries = 17; constexpr ResultCode ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625}; -LanguageCode GetLanguageCodeFromIndex(std::size_t index) { - return available_language_codes.at(index); +void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t num_language_codes) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(static_cast(num_language_codes)); } -template -static std::array MakeLanguageCodeSubset() { - std::array arr; - std::copy_n(available_language_codes.begin(), size, arr.begin()); - return arr; +void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t max_size) { + const std::size_t requested_amount = ctx.GetWriteBufferSize() / sizeof(LanguageCode); + const std::size_t copy_amount = std::min(requested_amount, max_size); + const std::size_t copy_size = copy_amount * sizeof(LanguageCode); + + ctx.WriteBuffer(available_language_codes.data(), copy_size); + PushResponseLanguageCode(ctx, copy_amount); } +} // Anonymous namespace -static void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t max_size) { - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(RESULT_SUCCESS); - if (available_language_codes.size() > max_size) { - rb.Push(static_cast(max_size)); - } else { - rb.Push(static_cast(available_language_codes.size())); - } +LanguageCode GetLanguageCodeFromIndex(std::size_t index) { + return available_language_codes.at(index); } void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_SET, "called"); - if (available_language_codes.size() > pre4_0_0_max_entries) { - ctx.WriteBuffer(MakeLanguageCodeSubset()); - } else { - ctx.WriteBuffer(available_language_codes); - } - PushResponseLanguageCode(ctx, pre4_0_0_max_entries); + GetAvailableLanguageCodesImpl(ctx, pre4_0_0_max_entries); } void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) { @@ -87,12 +80,7 @@ void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) { void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_SET, "called"); - if (available_language_codes.size() > post4_0_0_max_entries) { - ctx.WriteBuffer(MakeLanguageCodeSubset()); - } else { - ctx.WriteBuffer(available_language_codes); - } - PushResponseLanguageCode(ctx, post4_0_0_max_entries); + GetAvailableLanguageCodesImpl(ctx, post4_0_0_max_entries); } void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { @@ -102,9 +90,9 @@ void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { } void SET::GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx) { - PushResponseLanguageCode(ctx, post4_0_0_max_entries); - LOG_DEBUG(Service_SET, "called"); + + PushResponseLanguageCode(ctx, post4_0_0_max_entries); } void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { -- cgit v1.2.3