From ab64ae8c6386655cd2c1e27f026f56f60ab51f8e Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sun, 22 Jan 2023 00:58:19 -0500 Subject: [PATCH] slic3r: address sanitizer cleanup in ImGuiWrapper::load_svg ImGuiWrapper::load_svg previously could load an image that was not of the aspect ratio specified by the target_width and target_height, and as a result, could create an output vector that was smaller (or differently shaped!) than the target_width and target_height. GCC's Address Sanitizer flagged this because init_font was reading over the end of the allocated buffer, but this also meant that images with incorrect aspect ratios might get rendered to the font canvas incorrectly. To solve this, we pass the generated width and height out from load_svg, and use it when copying images later. --- src/slic3r/GUI/ImGuiWrapper.cpp | 26 ++++++++++++++++---------- src/slic3r/GUI/ImGuiWrapper.hpp | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index fe4d57fce..1582fe35a 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1636,7 +1636,7 @@ static const ImWchar ranges_keyboard_shortcuts[] = #endif // __APPLE__ -std::vector ImGuiWrapper::load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height) +std::vector ImGuiWrapper::load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight) { std::vector empty_vector; @@ -1667,6 +1667,9 @@ std::vector ImGuiWrapper::load_svg(const std::string& bitmap_name ::nsvgDeleteRasterizer(rast); ::nsvgDelete(image); + *outwidth = width; + *outheight = height; + return data; } @@ -1951,11 +1954,12 @@ void ImGuiWrapper::init_font(bool compress) if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) { assert(rect->Width == icon_sz); assert(rect->Height == icon_sz); - std::vector raw_data = load_svg(icon.second, icon_sz, icon_sz); + unsigned outwidth, outheight; + std::vector raw_data = load_svg(icon.second, icon_sz, icon_sz, &outwidth, &outheight); const ImU32* pIn = (ImU32*)raw_data.data(); - for (int y = 0; y < icon_sz; y++) { + for (unsigned y = 0; y < outheight; y++) { ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X); - for (int x = 0; x < icon_sz; x++) + for (unsigned x = 0; x < outwidth; x++) *pOut++ = *pIn++; } } @@ -1967,11 +1971,12 @@ void ImGuiWrapper::init_font(bool compress) if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) { assert(rect->Width == icon_sz); assert(rect->Height == icon_sz); - std::vector raw_data = load_svg(icon.second, icon_sz, icon_sz); + unsigned outwidth, outheight; + std::vector raw_data = load_svg(icon.second, icon_sz, icon_sz, &outwidth, &outheight); const ImU32* pIn = (ImU32*)raw_data.data(); - for (int y = 0; y < icon_sz; y++) { + for (unsigned y = 0; y < outheight; y++) { ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X); - for (int x = 0; x < icon_sz; x++) + for (unsigned x = 0; x < outwidth; x++) *pOut++ = *pIn++; } } @@ -1983,11 +1988,12 @@ void ImGuiWrapper::init_font(bool compress) if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id)) { assert(rect->Width == icon_sz); assert(rect->Height == icon_sz); - std::vector raw_data = load_svg(icon.second, icon_sz, icon_sz); + unsigned outwidth, outheight; + std::vector raw_data = load_svg(icon.second, icon_sz, icon_sz, &outwidth, &outheight); const ImU32* pIn = (ImU32*)raw_data.data(); - for (int y = 0; y < icon_sz; y++) { + for (unsigned y = 0; y < outheight; y++) { ImU32* pOut = (ImU32*)pixels + (rect->Y + y) * width + (rect->X); - for (int x = 0; x < icon_sz; x++) + for (unsigned x = 0; x < outwidth; x++) *pOut++ = *pIn++; } } diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 6b584a60c..5280b876b 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -223,7 +223,7 @@ private: void render_draw_data(ImDrawData *draw_data); bool display_initialized() const; void destroy_font(); - std::vector load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height); + std::vector load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight); static const char* clipboard_get(void* user_data); static void clipboard_set(void* user_data, const char* text);