From 8eec717cced307c05c2fbec3574ef7b2a2d4acc4 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 6da246b0c272b0f3a77eecdeefa19d3a53e2d8ac 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 9c03c5ac8a27a9f7b75f35471faf4edd004878fd 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);