From 3ec90dc6ef529590112eabc6df412fe18a085aab Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 24 Oct 2018 15:03:29 -0400 Subject: [PATCH 1/3] service/acc: Early return in failure case in LoadImage() Allows unindenting the other branch's code. --- src/core/hle/service/acc/acc.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index cf065c2e01..17e3aa0e2a 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -104,20 +104,20 @@ private: rb.Push(RESULT_SUCCESS); const FileUtil::IOFile image(GetImagePath(user_id), "rb"); - if (!image.IsOpen()) { LOG_WARNING(Service_ACC, "Failed to load user provided image! Falling back to built-in backup..."); ctx.WriteBuffer(backup_jpeg); rb.Push(backup_jpeg_size); - } else { - const auto size = std::min(image.GetSize(), MAX_JPEG_IMAGE_SIZE); - std::vector buffer(size); - image.ReadBytes(buffer.data(), buffer.size()); - - ctx.WriteBuffer(buffer.data(), buffer.size()); - rb.Push(buffer.size()); + return; } + + const auto size = std::min(image.GetSize(), MAX_JPEG_IMAGE_SIZE); + std::vector buffer(size); + image.ReadBytes(buffer.data(), buffer.size()); + + ctx.WriteBuffer(buffer.data(), buffer.size()); + rb.Push(buffer.size()); } void GetImageSize(Kernel::HLERequestContext& ctx) { From 6f00628564510e22eef1f3180d974a94b896c36a Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 24 Oct 2018 15:25:30 -0400 Subject: [PATCH 2/3] service/acc: Silence compiler warnings Silences compiler warnings related to truncation. This also introduces a small helper function to perform the clamping of the image size. --- src/core/hle/service/acc/acc.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 17e3aa0e2a..d17d784cf1 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -21,8 +21,6 @@ namespace Service::Account { -constexpr u32 MAX_JPEG_IMAGE_SIZE = 0x20000; - // TODO: RE this structure struct UserData { INSERT_PADDING_WORDS(1); @@ -39,6 +37,11 @@ static std::string GetImagePath(UUID uuid) { "/system/save/8000000000000010/su/avators/" + uuid.FormatSwitch() + ".jpg"; } +static constexpr u32 SanitizeJPEGSize(std::size_t size) { + constexpr std::size_t max_jpeg_image_size = 0x20000; + return static_cast(std::min(size, max_jpeg_image_size)); +} + class IProfile final : public ServiceFramework { public: explicit IProfile(UUID user_id, ProfileManager& profile_manager) @@ -112,12 +115,12 @@ private: return; } - const auto size = std::min(image.GetSize(), MAX_JPEG_IMAGE_SIZE); + const u32 size = SanitizeJPEGSize(image.GetSize()); std::vector buffer(size); image.ReadBytes(buffer.data(), buffer.size()); ctx.WriteBuffer(buffer.data(), buffer.size()); - rb.Push(buffer.size()); + rb.Push(size); } void GetImageSize(Kernel::HLERequestContext& ctx) { @@ -133,7 +136,7 @@ private: "Failed to load user provided image! Falling back to built-in backup..."); rb.Push(backup_jpeg_size); } else { - rb.Push(std::min(image.GetSize(), MAX_JPEG_IMAGE_SIZE)); + rb.Push(SanitizeJPEGSize(image.GetSize())); } } From 1e3b139cd720f835c767e84526258c1dd53d3435 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 24 Oct 2018 15:30:54 -0400 Subject: [PATCH 3/3] service/acc: Move fallback image to file scope This is just flat data, so it doesn't really need to be in the function itself. This also allows deduplicating the constant for the backup size in GetImageSize(). --- src/core/hle/service/acc/acc.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index d17d784cf1..c6437a6711 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -32,6 +32,19 @@ struct UserData { }; static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size"); +// Smallest JPEG https://github.com/mathiasbynens/small/blob/master/jpeg.jpg +// used as a backup should the one on disk not exist +constexpr u32 backup_jpeg_size = 107; +constexpr std::array backup_jpeg{{ + 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, + 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x06, 0x06, 0x05, + 0x06, 0x09, 0x08, 0x0a, 0x0a, 0x09, 0x08, 0x09, 0x09, 0x0a, 0x0c, 0x0f, 0x0c, 0x0a, 0x0b, 0x0e, + 0x0b, 0x09, 0x09, 0x0d, 0x11, 0x0d, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x10, 0x0a, 0x0c, 0x12, 0x13, + 0x12, 0x10, 0x13, 0x0f, 0x10, 0x10, 0x10, 0xff, 0xc9, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01, + 0x01, 0x01, 0x11, 0x00, 0xff, 0xcc, 0x00, 0x06, 0x00, 0x10, 0x10, 0x05, 0xff, 0xda, 0x00, 0x08, + 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9, +}}; + static std::string GetImagePath(UUID uuid) { return FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + "/system/save/8000000000000010/su/avators/" + uuid.FormatSwitch() + ".jpg"; @@ -89,19 +102,6 @@ private: void LoadImage(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_ACC, "called"); - // smallest jpeg https://github.com/mathiasbynens/small/blob/master/jpeg.jpg - // used as a backup should the one on disk not exist - constexpr u32 backup_jpeg_size = 107; - static constexpr std::array backup_jpeg{ - 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, - 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x08, 0x06, 0x06, 0x05, 0x06, 0x09, 0x08, 0x0a, 0x0a, 0x09, 0x08, 0x09, 0x09, 0x0a, - 0x0c, 0x0f, 0x0c, 0x0a, 0x0b, 0x0e, 0x0b, 0x09, 0x09, 0x0d, 0x11, 0x0d, 0x0e, 0x0f, - 0x10, 0x10, 0x11, 0x10, 0x0a, 0x0c, 0x12, 0x13, 0x12, 0x10, 0x13, 0x0f, 0x10, 0x10, - 0x10, 0xff, 0xc9, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x11, 0x00, - 0xff, 0xcc, 0x00, 0x06, 0x00, 0x10, 0x10, 0x05, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, - 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9, - }; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); @@ -125,7 +125,6 @@ private: void GetImageSize(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_ACC, "called"); - constexpr u32 backup_jpeg_size = 107; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS);