summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2019-05-09 20:41:33 -0400
committerGravatar Lioncash2019-05-09 21:28:36 -0400
commitc823cf6594c2ed8f69c84cabb9ed307496a55eff (patch)
tree7bd3aac7e6c5cce1a136cc518e1c6c342e70c342 /src
parentMerge pull request #2437 from lioncash/audctl (diff)
downloadyuzu-c823cf6594c2ed8f69c84cabb9ed307496a55eff.tar.gz
yuzu-c823cf6594c2ed8f69c84cabb9ed307496a55eff.tar.xz
yuzu-c823cf6594c2ed8f69c84cabb9ed307496a55eff.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/set/set.cpp56
1 files changed, 22 insertions, 34 deletions
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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include <chrono> 6#include <chrono>
6#include "common/logging/log.h" 7#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/client_port.h"
9#include "core/hle/kernel/client_session.h"
10#include "core/hle/service/set/set.h" 9#include "core/hle/service/set/set.h"
11#include "core/settings.h" 10#include "core/settings.h"
12 11
13namespace Service::Set { 12namespace Service::Set {
14 13namespace {
15constexpr std::array<LanguageCode, 17> available_language_codes = {{ 14constexpr std::array<LanguageCode, 17> available_language_codes = {{
16 LanguageCode::JA, 15 LanguageCode::JA,
17 LanguageCode::EN_US, 16 LanguageCode::EN_US,
@@ -32,41 +31,35 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{
32 LanguageCode::ZH_HANT, 31 LanguageCode::ZH_HANT,
33}}; 32}};
34 33
35constexpr std::size_t pre4_0_0_max_entries = 0xF; 34constexpr std::size_t pre4_0_0_max_entries = 15;
36constexpr std::size_t post4_0_0_max_entries = 0x40; 35constexpr std::size_t post4_0_0_max_entries = 17;
37 36
38constexpr ResultCode ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625}; 37constexpr ResultCode ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625};
39 38
40LanguageCode GetLanguageCodeFromIndex(std::size_t index) { 39void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t num_language_codes) {
41 return available_language_codes.at(index); 40 IPC::ResponseBuilder rb{ctx, 3};
41 rb.Push(RESULT_SUCCESS);
42 rb.Push(static_cast<u32>(num_language_codes));
42} 43}
43 44
44template <std::size_t size> 45void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t max_size) {
45static std::array<LanguageCode, size> MakeLanguageCodeSubset() { 46 const std::size_t requested_amount = ctx.GetWriteBufferSize() / sizeof(LanguageCode);
46 std::array<LanguageCode, size> arr; 47 const std::size_t copy_amount = std::min(requested_amount, max_size);
47 std::copy_n(available_language_codes.begin(), size, arr.begin()); 48 const std::size_t copy_size = copy_amount * sizeof(LanguageCode);
48 return arr; 49
50 ctx.WriteBuffer(available_language_codes.data(), copy_size);
51 PushResponseLanguageCode(ctx, copy_amount);
49} 52}
53} // Anonymous namespace
50 54
51static void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t max_size) { 55LanguageCode GetLanguageCodeFromIndex(std::size_t index) {
52 IPC::ResponseBuilder rb{ctx, 3}; 56 return available_language_codes.at(index);
53 rb.Push(RESULT_SUCCESS);
54 if (available_language_codes.size() > max_size) {
55 rb.Push(static_cast<u32>(max_size));
56 } else {
57 rb.Push(static_cast<u32>(available_language_codes.size()));
58 }
59} 57}
60 58
61void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { 59void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
62 LOG_DEBUG(Service_SET, "called"); 60 LOG_DEBUG(Service_SET, "called");
63 61
64 if (available_language_codes.size() > pre4_0_0_max_entries) { 62 GetAvailableLanguageCodesImpl(ctx, pre4_0_0_max_entries);
65 ctx.WriteBuffer(MakeLanguageCodeSubset<pre4_0_0_max_entries>());
66 } else {
67 ctx.WriteBuffer(available_language_codes);
68 }
69 PushResponseLanguageCode(ctx, pre4_0_0_max_entries);
70} 63}
71 64
72void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) { 65void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) {
@@ -87,12 +80,7 @@ void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) {
87void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) { 80void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) {
88 LOG_DEBUG(Service_SET, "called"); 81 LOG_DEBUG(Service_SET, "called");
89 82
90 if (available_language_codes.size() > post4_0_0_max_entries) { 83 GetAvailableLanguageCodesImpl(ctx, post4_0_0_max_entries);
91 ctx.WriteBuffer(MakeLanguageCodeSubset<post4_0_0_max_entries>());
92 } else {
93 ctx.WriteBuffer(available_language_codes);
94 }
95 PushResponseLanguageCode(ctx, post4_0_0_max_entries);
96} 84}
97 85
98void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { 86void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) {
@@ -102,9 +90,9 @@ void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) {
102} 90}
103 91
104void SET::GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx) { 92void SET::GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx) {
105 PushResponseLanguageCode(ctx, post4_0_0_max_entries);
106
107 LOG_DEBUG(Service_SET, "called"); 93 LOG_DEBUG(Service_SET, "called");
94
95 PushResponseLanguageCode(ctx, post4_0_0_max_entries);
108} 96}
109 97
110void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { 98void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {